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

时间:2012-10-10 00:45:55

标签: python

代码1

x = 0

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

print(x)

结果1

0
1
0

代码2

x = 0

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

foo()

结果2

UnboundLocalError: local variable 'x' referenced before assignment.

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


更新

多次阅读Python Docs后,我仍然无法理解范围规则。

  

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

     

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

     

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

3 个答案:

答案 0 :(得分: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)

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()

答案 1 :(得分:1)

要使示例具有可比性,请不要忘记使用global statement

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

这样你就不会得到UnboundLocalError

答案 2 :(得分:1)

类块不知道“局部”变量,只知道类变量。它们与局部变量的不同之处在于它们在执行块后不会被遗忘;他们将继续作为课堂上的领域。本地和类变量的处理方式不仅仅是这方面,因此不会引发未绑定的错误。毕竟你没有一个未定义的局部变量遮蔽全局变量。因此,在定义类变量之前访问全局变量是没有问题的。

也许编译器应该以某种方式警告这一点,但目前它没有。