python中类块和功能块之间的差异

kev*_*kev 7 python

代码1

x = 0

class Foo:
    print(x)
    x = 1
    print(x)

print(x)
Run Code Online (Sandbox Code Playgroud)

结果1

0
1
0
Run Code Online (Sandbox Code Playgroud)

代码2

x = 0

def foo():
    print(x)
    x = 1
    print(x)

foo()
Run Code Online (Sandbox Code Playgroud)

结果2

UnboundLocalError: local variable 'x' referenced before assignment.
Run Code Online (Sandbox Code Playgroud)

为什么x可以引用两个名称空间中的对象class block
我不明白为什么Code 1不扔一个UnboundLocalError.
功能和课堂之间的不一致让我烦恼.


更新:

在阅读了几次Python文档之后,我仍然无法理解范围规则.

以下是块:模块,函数体和类定义....[跳跃]...

如果名称绑定在块中,则它是该块的局部变量,除非声明为非本地.如果名称在模块级别绑定,则它是全局变量.(模块代码块的变量是局部的和全局的.)如果在代码块中使用了变量但在那里没有定义,则它是一个自由变量.

如果名称绑定操作发生在代码块中的任何位置,则块中名称的所有使用都将被视为对当前块的引用.在绑定之前在块中使用名称时,这可能会导致错误.这条规则很微妙.Python缺少声明,并允许在代码块中的任何位置进行名称绑定操作.可以通过扫描块的整个文本以确定名称绑定操作来确定代码块的局部变量.

Joh*_*ooy 6

x = 0

class Foo:
    print(x)   # Foo.x isn't defined yet, so this is the global x
    x = 1      # This is referring to Foo.x
    print(x)   # So is this

print(x)
Run Code Online (Sandbox Code Playgroud)
x = 0

def foo():
    print(x)   # Even though x is not defined yet, it's known to be local
               # because of the assignment
    x = 1      # This assignment means x is local for the whole function
    print(x)

foo()
Run Code Online (Sandbox Code Playgroud)