NameError:全局名称未定义

2 投票
2 回答
6994 浏览
提问于 2025-04-16 23:38

我知道有很多类似的问题,但那些并没有帮助我理解我的问题。而且我有三个模块:

第一个模块是 model

from datetime import datetime
from elixir import *
from run_test import create_db
from sqlalchemy.schema import UniqueConstraint
class ValueTest(Test): 
    value = Field(Integer)
    def __init__(self, name, value):
        '''
        Constructor
        '''
        self.name = name;
        self.value = value

如果我从第二个模块 run_test 运行测试方法,就没有任何问题

from model import *
def main():
    test();
def test():
    test = ValueTest("test",2)
if __name__ == "__main__":
    main()

但是当我尝试这样做时,我遇到了一个大家都知道的错误 NameError: global name 'ValueTest' is not defined

import run_test
def main():
    run_test.test()
if __name__ == '__main__':
    main()

2 个回答

-1

问题在于你出现了循环导入。也就是说,run_test在导入model,而model又在导入run_test。当出现循环导入时,会发生一些奇怪的事情。如果可以的话,把一些公共的函数(比如你提到的create_db)放到另一个模块里,这样model就可以从那个模块导入,而不是从run_test导入。

6

当你导入一个模块时,你并不是把这个模块里面引入的所有名字都导入过来;你只会导入这个模块自己定义的名字。你在最后的脚本中还是需要写 from model import ValueTest

如果 from foo import *foo 导入的所有名字都带过来,那你用 import something 的时候,可能也会把 ossys 里面的所有东西都导入进来。这会变得非常麻烦。


其实,这个说法是不对的。从模块中导入的符号(名字)只有在这个模块里定义的 __all__ 列表中的那些。如果没有这个列表,所有不以 _ 开头的名字确实会被导入。

感谢Ethan的纠正。

撰写回答