0

这是代码:

#a.py
ALL_FUNC = [bar, foo]  #a list containing all the functions defined in this module

def bar():
    pass

def foo():
    pass

然后,我像这样运行它: $ python a.py NameError: name 'bar' is not defined

错误意味着,在执行bar时未定义。但是为什么解释器在模块中ALL_FUNC = [bar, foo]找不到函数呢?bar仅仅因为bar是在ALL_FUNC?

看这个,这是一个python类,

class A:
    def __init__(self):
        self.bar()

    def bar(self):
        pass

a = A()

显然,上面的代码会运行没有任何错误,但是barinA也是在访问它的位置(in __init__)之后定义的,为什么self.bar()可以找到没有任何错误?

跟进

这是另一个模块,

#b.py
def bar():
    print k  #well, apparently this line will result in an error
def foo():
    pass

if __name__ == '__main__':
    foo()

然后像这样运行,

$ python b.py

没有错误!为什么?bar应该会导致错误,不是吗?就因为没有在 中使用__main__,所以没有检测到错误?但是bar的定义被执行了,对吧?

4

2 回答 2

2

解释器从上到下执行脚本。

def是一个可执行语句。在执行相关语句之前,由def(例如在您的第一个示例中)创建的任何名称都不存在。foobardef

现在来看您的第二个示例:名称在被调用self.bar()时被解析,并且在看到整个类定义后被调用。__init__()

于 2012-02-20T13:19:59.630 回答
2

But why can't the interpreter find the function bar in the module? Just because bar is defined after ALL_FUNC?

Because the code is executed in the order it appears in the file. Where you try to assign the values to ALL_FUNC the function definitions haven't been executed.

but bar in A is also defined after where it's accessed (in __init__), why self.bar() can be found without any error?

Because __init__ has been called after the class has been defined. Your class is instantiated by a = A(), after the class definition.


Response to Follow up

Why? bar is supposed to result in an error, isn't it? Just because it's not used in __main__, so the error isn't detected? But bar's definition is executed, right?

If you called bar() you'd get a NameError. When you defined the bar function, the function code was interpreted, not executed. I'm not sure whether this would ever pick up anything other than SyntaxErrors, but definitely not NameErrors.

However, bar won't always result in an error. Consider:

>>> def bar():
...   print(k)
...
>>> bar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in bar
NameError: global name 'k' is not defined
>>> k = "Foo"
>>> bar()
Foo
于 2012-02-20T13:24:10.657 回答