python:澄清名称解析?

时间:2019-04-24 12:42:01

标签: python

我正在阅读python参考文献name resolution,其内容为

  

类定义是可以使用和定义名称的可执行语句。这些引用遵循通常的名称解析规则,但在全局命名空间中查找未绑定的局部变量。

基于此,我希望获得以下代码

x = 10

def f():
    x = 5

    class Test:
        y = x

    return Test

print(f().y)

打印10,但是打印5。这是参考文献中的错误,还是我误会了什么?

3 个答案:

答案 0 :(得分:4)

在这种情况下,“正常”规则适用:

x = 'global'

def f():
    x = 'defined in f'

    class Test:
        print(x) # not local, normal rules apply

f()
# defined in f

在第二种情况下,如果我们在函数内部,我们将期望UnboundLocalError: local variable 'x' referenced before assignment

x = 'global'

def f():
    x = 'defined in f'

    class Test:
        print(x) # unbound local at this time
        x = 'assigned in Test'
        print(x)

但是对于第一个print(x)x将从全局命名空间中获取:

f()
# global
# assigned in Test

答案 1 :(得分:0)

我认为@khelwood给出了答案。变量中的值:

  

Test.y

是您定义的整数,但是永远不要给函数赋予x = 10。

也许您真正想要的是:

x = 10
def f(x=5):
    class Test:
        y = x
    return Test
print(f().y) #print default 5
print(f(x).y) 

由于x被赋予该函数,因此最后一行打印10,因此该类将y设置为x

答案 2 :(得分:0)

您可以通过将f包装在另一个定义局部变量x的函数中来查看异常:

x = 10

def g():
    x = 7
    def f():
        class Test:
            y = x

        return Test
    return f()

print(g().y)

现在输出为7,因为在x语句中对class的查找会绕过g的局部范围来查找x的全局值。

在您的代码中,由于class建立了新的命名空间,但没有建立新的 scope ,因此x的值取自当前的本地范围,f的范围。