【问题标题】:nonlocal statement got checked without running the function in python [duplicate]未在python中运行该函数就检查了非本地语句[重复]
【发布时间】:2018-12-19 14:46:10
【问题描述】:

之前我以为我们定义一个函数的时候,这个函数可能是错的,但是python直到它被执行才检查它:

x = 100

def f():
    x = 1/0
    return x

print(x)
# >>> 100

然而,当我在学习nonlocal 声明时

x = 100

def f():
    def g():
        nonlocal x
        x = x * 99
        return x
    return g

print(x)
# >>> SyntaxError: no binding for nonlocal 'x' found

即使函数没有执行,它也被检出。

在哪里可以找到官方的解释?

变量边界情况的补充:

x = 100
def f():
    global x
    global xx
    x = 99
    return x

print(f())
# >>> 99
print(x)
# >>> 99

如果我global 一些根本不存在的变量,它似乎完全没问题? 而且即使我执行这个函数也不会带来任何错误?

这部分被移到一个新的个人问题: Why am I able to global a non-existing varlable in python

【问题讨论】:

  • nonlocal 表示该名称存在于外部词法函数作用域中,在上面的示例中,外部词法函数作用域是 f() 因为你没有得到绑定异常。更多细节 - stackoverflow.com/questions/8050502/…
  • @MONTYHS 我知道nonlocal 是做什么的,我只是想问为什么在函数没有执行时会检查这个

标签: python


【解决方案1】:

nonlocal 检查最近的封闭范围不包括全局变量(即模块级变量)。也就是说,你的 f() 函数应该声明一个 x 才能工作,因为 nonlocal 看不到全局 x = 100 变量。

https://docs.python.org/3/reference/simple_stmts.html#the-global-statement

至于为什么不运行函数就报错,是因为变量名是在编译时绑定的,所以你不使用这个函数也没关系全部。看 https://docs.python.org/3/reference/executionmodel.html#resolution-of-names

但是,global 有不同的行为。就像nonlocal 如果global x 已经存在,则使用它而不是本地的。但是,如果不是,则意味着“如果我创建了一个名为 x 的变量,则在全局范围内创建它,而不是在函数范围内”。所以,在你的例子中

x = 100
def f():
    global x
    global xx
    x = 99
    xx = 123
    return x

print(f()) # 99
print(x)   # 99
print(xx)  # 123

xx 变量已出现在全局命名空间中。虽然它只是对编译器的一个提示,所以如果你声明global xx 而不分配它,然后尝试print(xx),你仍然会得到一个NameError 使用未定义的变量

【讨论】:

  • 我了解nonlocal 的作用,但我更感兴趣的是为什么在我根本不运行此功能时会检查它。
  • @Code_Control_jxie0755:对不起,我看错了问题,将编辑答案
  • @Code_Control_jxie0755:已编辑
  • 所以发生这种情况是因为它会检查所有变量的边界,但大多数情况下,如果之前没有找到该变量,它将被假定为一个新的变量创建,这样就不会出错.但在这种情况下,nonlocal 建议“不要创建新变量,而是寻找现有的变量来绑定”,这将导致问题。我是否正确理解这一点?
  • @Code_Control_jxie0755:完全正确。这发生在程序运行之前
猜你喜欢
  • 1970-01-01
  • 2010-11-18
  • 1970-01-01
  • 2018-03-30
  • 2022-01-20
  • 1970-01-01
相关资源
最近更新 更多