«Наименьшее удивление» и изменчивый аргумент по умолчаниюPython

Программы на Python
Ответить
Anonymous
 «Наименьшее удивление» и изменчивый аргумент по умолчанию

Сообщение Anonymous »

Любого, кто достаточно долго занимается Python, сталкивался (или разрывал на куски) следующая проблема:

Код: Выделить всё

def foo(a=[]):
a.append(5)
return a
Новичкам Python следует ожидать, что эта функция, вызываемая без параметра, всегда будет возвращать список только с одним элементом: [5]. Вместо этого результат совсем другой и очень удивительный (для новичка):

Код: Выделить всё

>>> foo()
[5]
>>> foo()
[5, 5]
>>> foo()
[5, 5, 5]
>>> foo()
[5, 5, 5, 5]
>>> foo()
Один мой менеджер однажды впервые столкнулся с этой функцией и назвал ее «серьезным недостатком дизайна» языка. Я ответил, что такое поведение имеет подспудное объяснение, и оно действительно очень загадочное и неожиданное, если вы не понимаете его внутренностей. Однако я не смог ответить (себе) на следующий вопрос: в чем причина привязки аргумента по умолчанию при определении функции, а не при ее выполнении? Я сомневаюсь, что опытное поведение имеет практическое применение (кто действительно использовал статические переменные в C, не порождая ошибок?)
Редактировать:
Бачек привел интересный пример. Вместе с большинством ваших комментариев и особенно Утаала я уточнил:

Код: Выделить всё

def a():
print("a executed")
return []

def b(x=a()):
x.append(5)
print(x)

a executed
>>> b()
[5]
>>> b()
[5, 5]
Мне кажется, что дизайнерское решение было связано с тем, куда поместить область параметров: внутри функции или «вместе» с ней?
Выполнение привязки внутри функции будет означать, что x фактически привязан к указанному значению по умолчанию, когда функция вызывается, а не определена, что представляет собой серьезный недостаток: строка def будет выглядеть так: «гибридный» в том смысле, что часть привязки (объекта функции) будет происходить при определении и часть (присвоение параметров по умолчанию) во время вызова функции.
Фактическое поведение более последовательное: все в этой строке оценивается при выполнении этой строки, то есть при определении функции. .

Подробнее здесь: https://stackoverflow.com/questions/113 ... t-argument
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»