Иногда кажется естественным иметь параметр по умолчанию, который представляет собой пустой список. Однако Python дает неожиданное поведение в этих ситуациях .
Если, например, у меня есть функция:
def my_func(working_list = []):
working_list.append("a")
print(working_list)
При первом вызове будет работать значение по умолчанию, но после этого вызовы обновят существующий список (с одной буквой «а» для каждого вызова) и распечатают обновленную версию.
Итак, каков питонический способ добиться желаемого поведения (свежий список при каждом вызове)?
python
python-3.x
Джон Малдер
источник
источник
Ответы:
В документации говорится, что вы должны использовать
None
по умолчанию и явно проверять его в теле функции.источник
f()
список, вам нужно будет вызвать,f(*l)
что является грубым. Хуже того, реализацияmate(['larch', 'finch', 'robin'], ['bumble', 'honey', 'queen'])
SUCK w / varargs. Намного лучше, если это такdef mate(birds=[], bees=[]):
.Существующие ответы уже предоставили прямые решения, о которых просили. Однако, поскольку это очень распространенная ошибка для начинающих программистов Python, стоит добавить объяснение, почему python ведет себя таким образом, которое красиво резюмировано в " Автостопом по Python " как " Изменяемые аргументы по умолчанию ": http: // docs .python-guide.org / en / latest / writing / gotchas /
Цитата: « Аргументы Python по умолчанию оцениваются один раз, когда функция определена, а не каждый раз, когда функция вызывается (как, скажем, в Ruby). Это означает, что если вы используете изменяемый аргумент по умолчанию и измените его, вы получите изменил этот объект для всех будущих вызовов функции "
Пример кода для его реализации:
источник
В данном случае это не имеет значения, но вы можете использовать идентификацию объекта для проверки None:
Вы также можете воспользоваться тем, как логический оператор или определен в python:
Хотя это будет вести себя неожиданно, если вызывающий дает вам пустой список (который считается ложным) как working_list и ожидает, что ваша функция изменит список, который он ему дал.
источник
Если целью функции является изменение параметра, переданного как
working_list
, см. Ответ HenryR (= None, отметьте None внутри).Но если вы не собирались изменять аргумент, просто используйте его как отправную точку для списка, вы можете просто скопировать его:
(или в этом простом случае,
print starting_list + ["a"]
но я думаю, это был просто игрушечный пример)В общем, изменение аргументов - плохой стиль в Python. Единственные функции, от которых ожидается полное изменение объекта, - это методы объекта. Еще реже изменять необязательный аргумент - действительно ли побочный эффект, возникающий только в некоторых вызовах, является лучшим интерфейсом?
Если вы делаете это по привычке C «выходных аргументов», это совершенно не нужно - вы всегда можете вернуть несколько значений в виде кортежа.
Если вы делаете это для эффективного построения длинного списка результатов без создания промежуточных списков, подумайте о том, чтобы написать его как генератор и использовать,
result_list.extend(myFunc())
когда вы его вызываете. Таким образом, ваши соглашения о вызовах остаются очень чистыми.Один из шаблонов, в которых часто выполняется изменение необязательного аргумента , - это скрытый аргумент «памятка» в рекурсивных функциях:
источник
Возможно, я не по теме, но помните, что если вы просто хотите передать переменное количество аргументов, питонический способ - передать кортеж
*args
или словарь**kargs
. Это необязательно и лучше, чем синтаксисmyFunc([1, 2, 3])
.Если вы хотите передать кортеж:
Если вы хотите передать словарь:
источник
Уже даны хорошие и правильные ответы. Я просто хотел дать другой синтаксис для написания того, что вы хотите сделать, что я считаю более красивым, когда вы, например, хотите создать класс с пустыми списками по умолчанию:
В этом фрагменте кода используется синтаксис оператора if else. Мне он особенно нравится, потому что это аккуратный однострочник без двоеточий и т.д., и он почти читается как обычное английское предложение. :)
В вашем случае вы можете написать
источник
Я взял курс расширения UCSC
Python for programmer
Что верно для: def Fn (data = []):
Ответ:
источник