Простой Python. современный стиль программирования - читать онлайн бесплатно полную версию книги . Страница 90

Если вы предоставите аргумент, он будет использован вместо аргумента по

умолчанию:

>>> menu('dunkelfelder', 'duck', 'doughnut')

{'dessert': 'doughnut', 'wine': 'dunkelfelder', 'entree': 'duck'}

Значение аргументов по умолчанию высчитывается, когда функция определяется, а не вы-

полняется. Распространенной ошибкой новичков (и иногда не совсем новичков) является

использование изменяемого типа данных вроде списка или словаря в качестве аргумента

по умолчанию.

В следующей проверке ожидается, что функция buggy() будет каждый раз за-

пускаться с новым пустым списком result, добавлять в него аргумент arg, а затем

выводить на экран список, состоящий из одного элемента. Однако в этой функции

есть баг: список будет пуст только при первом вызове. Во второй раз список result

будет содержать элемент, оставшийся после предыдущего вызова:

>>> def buggy(arg, result=[]):

... result.append(arg)

... print(result)

...

>>> buggy('a')

['a']

>>> buggy('b') # ожидаем увидеть ['b']

['a', 'b']

Функция работала бы корректно, если бы код выглядел так:

>>> def works(arg):

... result = []

... result.append(arg)

... return result

...

>>> works('a')

['a']

>>> works('b')

['b']

124

Глава 4. Корочка Python: структуры кода

Решить проблему можно, передав в функцию что-то еще, чтобы указать на то,

что вызов является первым:

>>> def nonbuggy(arg, result=None):

... if result is None:

... result = []

... result.append(arg)

... print(result)

...

>>> nonbuggy('a')

['a']

>>> nonbuggy('b')

['b']

Получаем позиционные аргументы с помощью *

Если вы работали с языками программирования C или C++, то можете предпо-

ложить, что астериск (*) в Python как-то относится к указателям. Это не так, Python

не имеет указателей.

Если символ * будет использован внутри функции с параметром, произвольное