在Python中将名称传递给嵌套函数?

在Python中将名称传递给嵌套函数?,python,python-3.x,Python,Python 3.x,在嵌套函数中使用名称和将名称传递给嵌套函数之间有什么区别(如果有的话)?如果没有区别,按惯例哪一个更受欢迎 def foo(bar): def put(): bar.append('World!') print(', '.join(bar)) put() foo(['Hello']) 对 def foo(bar): def put(bar): bar += ['World!'] print(', '.joi

在嵌套函数中使用名称和将名称传递给嵌套函数之间有什么区别(如果有的话)?如果没有区别,按惯例哪一个更受欢迎

def foo(bar):
    def put():
        bar.append('World!')
        print(', '.join(bar))
    put()
foo(['Hello'])

def foo(bar):
    def put(bar):
        bar += ['World!']
        print(', '.join(bar))
    put(bar)
foo(['Hello'])

区别在于,在第一个函数中,bar变量在父函数的范围内,可以在子函数中使用,除非您对其进行赋值(这种情况类似于在函数中使用
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
>>> def foo(bar):
...     def put():
...         nonlocal bar
...         bar = bar + ['World!']
...         print(', '.join(bar))
...     put()
...
>>> foo(['Hello'])
Hello, World!
>>> def foo(bar):
...     def put(bar):
...         bar = bar + ['World!']
...         print(', '.join(bar))
...     put(bar)
...
>>>
>>> foo(['Hello'])
Hello, World!

而在第二个函数中,bar是
put()
函数的局部变量(因为它是函数的一个参数),可以在没有上述
UnboundLocalError
的情况下赋值,例如-

>>> 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
>>> def foo(bar):
...     def put():
...         nonlocal bar
...         bar = bar + ['World!']
...         print(', '.join(bar))
...     put()
...
>>> foo(['Hello'])
Hello, World!
>>> def foo(bar):
...     def put(bar):
...         bar = bar + ['World!']
...         print(', '.join(bar))
...     put(bar)
...
>>>
>>> foo(['Hello'])
Hello, World!

我更愿意像在第二种情况下那样显式地传递所需的参数。

因为您只讨论嵌套函数,而不是闭包,除非您有特定的理由将其嵌套,否则我建议在模块范围中定义每个函数:

def put(bar):
    bar += ['World!']
    print(', '.join(bar))


def foo(bar):
    put(bar)


foo(['Hello'])

如果出于某种原因确实需要嵌套,最好显式地传入
bar
。然而,如果您确实认为需要嵌套,请首先询问您的推理;你很有可能不这么做

相关:正如Python的禅宗所言,“显式优于隐式”。在这种情况下,显式传递参数比猜测
bar
突然从何而来更为清晰。您是在谈论嵌套函数,而不是闭包吗?也就是说,您是否不打算将
put
作为
foo
的返回值返回?@Cyphase我不是在谈论闭包,除非这会影响到选项之间的选择。谢谢你的澄清。伊恩,我会先说我同意@Wolph的观点,即显式比隐式好。也就是说,与单独定义嵌套函数相比,您需要嵌套函数有什么原因吗?在我看来,这是更好的选择。如果在第二种情况下(通过使用
bar.append
+=
)不指定
bar
),那么
bar
不是本地的,对吗?在
put(bar)
之后,其值也将在foo范围内发生变化。所以在我的片段中。。。实际上没有区别?在第二种情况下,无论您是否赋值,bar始终是内部函数的局部。但在你们的例子中,是的,无论酒吧是不是本地的,都不会有什么区别。