嵌套在函数中的类和属性查找
下面的代码运行得很好,也就是说,它没有出现任何错误:
def foo(arg):
class Nested(object):
x = arg
foo('hello')
但是下面的代码就会抛出一个异常,也就是出现错误:
def foo(arg):
class Nested(object):
arg = arg # note that names are the same
foo('hello')
错误追踪信息:
Traceback (most recent call last):
File "test.py", line 6, in <module>
foo('hello')
File "test.py", line 3, in foo
class Nested(object):
File "test.py", line 4, in Nested
arg = arg
NameError: name 'arg' is not defined
我不太明白为什么会出现这样的情况。有人能解释一下吗?
3 个回答
3
这是因为Python的作用域规则:
def foo(arg): # (1)
class Nested(object):
arg = arg # (2)
(2) 在类的命名空间中定义了一个新的'arg'名字,这样就遮住了外部命名空间中其他'arg'的值(1)。
不过,(2) 是不必要的,下面的写法是完全有效的:
def foo(arg):
class Nested(object):
def message(self):
print arg
return Nested()
nested = foo('hello')
nested.message()
(打印 hello
)
3
如果你在一个函数里面给一个变量赋值,Python会认为这个变量是这个函数内部的局部变量。所以,当你试图把arg的值赋给它自己时,其实你是在暗示Python把它当作一个局部变量来处理。
5
这里的 arg
属性会覆盖掉 arg
这个函数的参数,这就是所谓的“内部作用域”。
def foo(arg):
class Nested(object):
arg = arg # you try to read the `arg` property which isn't initialized
如果你在解释器窗口里输入 i = i
,而之前没有给 i
这个变量赋值,你也会遇到同样的错误。