Разница заключается в том, что в первом, переменный бар находится в рамках родительской функции, он может быть использован в функции ребенка, если вы не сделаете задание на нем (Это было бы аналогично использованию global
переменных в функции). Пример -
>>> def foo(bar):
... def put():
... bar = bar + ['World']
... print(', '.join(bar))
... put()
...
>>>
>>> foo(['Hello'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in foo
File "<stdin>", line 3, in put
UnboundLocalError: local variable 'bar' referenced before assignment
В этом случае, если вы хотите использовать bar
и назначить на него, а также, что вам нужно использовать nonlocal
ключевое слово, пример -
>>> def foo(bar):
... def put():
... nonlocal bar
... bar = bar + ['World!']
... print(', '.join(bar))
... put()
...
>>> foo(['Hello'])
Hello, World!
В то время как во втором один, бар является локальной переменной для функции put()
(потому что ее аргумент для нее) и может быть назначен без вышеуказанного UnboundLocalError
, пример -
>>> def foo(bar):
... def put(bar):
... bar = bar + ['World!']
... print(', '.join(bar))
... put(bar)
...
>>>
>>> foo(['Hello'])
Hello, World!
Я бы предпочел явно передать необходимые аргументы, как это было сделано во втором случае.
related: http://stackoverflow.com/questions/1261875/python-nonlocal-statement – NightShadeQueen
Как диктует Дзен Питона: «Явный лучше, чем неявный». В этом случае явное прохождение аргумента яснее, чем догадываться, откуда неожиданно появился «бар». – Wolph
Вы говорите только о вложенных функциях, а не о закрытии? Значит, вы не собираетесь возвращать 'put' в качестве возвращаемого значения' foo'? – Cyphase