Я собираюсь продемонстрировать альтернативную структуру, чтобы передать значение списка по умолчанию функции (она одинаково хорошо работает со словарями).
Поскольку другие подробно комментируют, параметр списка привязан к функции, когда она определена, а не когда она выполняется. Поскольку списки и словари изменяемы, любое изменение этого параметра влияет на другие вызовы этой функции. В результате последующие вызовы функции получат этот общий список, который может быть изменен любыми другими вызовами функции. Хуже того, два параметра используют общий параметр этой функции, в то же время не обращая внимания на изменения, сделанные другим.
Неверный метод (возможно ...):
def foo(list_arg=[5]):
return list_arg
a = foo()
a.append(6)
>>> a
[5, 6]
b = foo()
b.append(7)
# The value of 6 appended to variable 'a' is now part of the list held by 'b'.
>>> b
[5, 6, 7]
# Although 'a' is expecting to receive 6 (the last element it appended to the list),
# it actually receives the last element appended to the shared list.
# It thus receives the value 7 previously appended by 'b'.
>>> a.pop()
7
Вы можете убедиться, что это один и тот же объект, используя id
:
>>> id(a)
5347866528
>>> id(b)
5347866528
Per Brett Slatkin's «Эффективный Python: 59 конкретных способов записи лучшего Python», Пункт 20: Использование None
и Docstrings для указания динамических аргументов по умолчанию (стр. 48)
Соглашение о достижении желаемого результата в Python заключается в предоставлении значения по умолчанию
blockquote>None
и документируйте фактическое поведение в docstring.Эта реализация гарантирует, что каждый вызов функции либо получает список по умолчанию, либо список, переданный функции.
Предпочтительный Метод:
def foo(list_arg=None): """ :param list_arg: A list of input values. If none provided, used a list with a default value of 5. """ if not list_arg: list_arg = [5] return list_arg a = foo() a.append(6) >>> a [5, 6] b = foo() b.append(7) >>> b [5, 7] c = foo([10]) c.append(11) >>> c [10, 11]
В «Неправильном методе» могут быть законные варианты использования, в соответствии с которыми программист предполагает, что параметр списка по умолчанию должен быть общим, но это скорее исключение, чем правило.