嵌套在函数中的类和属性查找

4 投票
3 回答
1032 浏览
提问于 2025-04-15 13:23

下面的代码运行得很好,也就是说,它没有出现任何错误:

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 这个变量赋值,你也会遇到同样的错误。

撰写回答