gpt4 book ai didi

python - 赋值是在 Python 的函数调用中进行的吗?

转载 作者:太空宇宙 更新时间:2023-11-04 02:51:57 28 4
gpt4 key购买 nike

在构建参数化装饰器时,我没有意识到在 Python 中不允许对嵌套函数中传入的参数进行重新分配。进一步看,我意识到对于简​​单的函数也是如此。我已将演示缩减为以下嵌套函数:

def a(s):
def b():
def c():
# nonlocal s # fix
print(s)
# while s:
# s -= 1 # uncommenting raises UnboundLocalError
print(s)
return None
return c()
return b()

a(3)
# 3
# 3

我希望通过添加注释的 while 循环获得以下所需的输出:

a(3)
# 3
# 0

接下来,取消注释 while 循环的两行会出现以下错误,这表明将值重新分配给 s 会引发错误:

<ipython-input-37-7141eb599936> in c()
3 def c():
4 # nonlocal s # fix
----> 5 print(s)
6 while s:
7 s -= 1 # uncommenting raises UnboundLocalError

UnboundLocalError: local variable 's' referenced before assignment

最后,取消注释 nonlocal 修复了这个问题,并按照 this post 的建议提供了所需的输出。 .

虽然问题解决了,但还是想了解一下问题的根源。我注意到回溯指向第一次使用参数化参数 s(例如 print(s)),而不是指向实际导致错误的行(即while 循环/赋值)。

我怀疑在调用一个函数时,Python 首先建立局部作用域的赋值。然后,赋值优先于或覆盖从外部作用域继承的变量。因此,如果没有分配给 s,则使用外部 s。相比之下,对于赋值,s 在函数调用时被重新定义,并且在初始赋值之前的任何引用都会引发错误。这是正确的,还是有人可以解释 Python 实际在做什么?

最佳答案

如果函数包含对变量的赋值(包括扩充赋值,例如 -=,则该变量自动为局部变量,除非显式声明为 global(或 nonlocal)。如果没有赋值,它自动是全局的,不需要任何声明(因为当没有值的来源时它几乎不可能是局部变量)。在任何代码被执行之前执行此分析生成的,所以你会遇到这样的情况,即后续的代码行可能导致前面的代码行成为错误。

关于python - 赋值是在 Python 的函数调用中进行的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43600957/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com