以下是代码:
#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:名称'bar'未定义
错误表示bar
执行时未定义ALL_FUNC = [bar, foo]
。但为什么解释器不能在模块中找到函数bar
?只是因为在bar
之后定义ALL_FUNC
?
看看这个,这是一个python类,
class A:
def __init__(self):
self.bar()
def bar(self):
pass
a = A()
显然,上面的代码会在没有任何错误的情况下运行,但bar
中的A
也会在访问它之后定义(在__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
的定义是执行的,对吧?
答案 0 :(得分:2)
解释器从上到下执行脚本。
def
是一个可执行语句。在执行相关def
语句之前,foo
创建的任何名称(例如第一个示例中的bar
和def
)都不存在。
现在转到第二个示例:当self.bar()
被称为时,名称__init__()
被解析,而整个类定义之后被称为被人看见了。
答案 1 :(得分:2)
但是为什么解释器不能在模块中找到功能栏?只是因为bar是在ALL_FUNC之后定义的?
因为代码按照它在文件中出现的顺序执行。在尝试将值分配给ALL_FUNC
时,函数定义尚未执行。
但A中的栏也是在访问它之后定义的(在__init__
中),为什么可以找到self.bar()
而没有任何错误?
因为在定义了类之后调用了__init__
。在类定义之后,您的类由a = A()
实例化。
对跟进的回应
为什么? bar
应该会导致错误,不是吗?仅仅因为__main__
没有使用它,所以没有检测到错误?但是bar的定义是执行的,对吗?
如果您致电bar()
,则会获得NameError
。定义bar
函数时,函数代码解释,而不是执行。我不确定除了SyntaxError
s之外是否还会提取其他内容,但绝对不是NameError
s。
但是,bar
并不总是会导致错误。考虑:
>>> 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