AttributeError: '模块'对象没有属性

254 投票
20 回答
910607 浏览
提问于 2025-04-15 13:28

我有两个Python模块:

a.py

import b

def hello():
  print "hello"

print "a.py"
print hello()
print b.hi()

b.py

import a

def hi():
  print "hi"

当我运行 a.py 时,我得到了:

AttributeError: 'module' object has no attribute 'hi'

这个错误是什么意思?我该怎么修复它?

20 个回答

54

这个问题是因为模块之间有循环依赖。也就是说,a 模块需要引入 b 模块,而 b 模块又需要引入 a 模块。但是其中一个模块必须先加载。在这个例子中,Python 会先初始化 a 模块,然后才是 b 模块。这样一来,当你在 a 中尝试访问 b.hi() 时,b 还没有完全加载好,所以 b.hi() 这个东西还不存在。

119

我也遇到过这个错误,原因是我不小心把一个模块命名成了和Python标准库里某个模块一样的名字。例如,我有一个叫commands的模块,而这个名字也是Python库里的一个模块。这个问题很难找到,因为在我本地的开发环境中一切正常,但在Google App Engine上运行时却出现了指定的错误。

242

你有互相引用的顶级导入,这几乎总是个坏主意。

如果你真的需要在Python中使用互相导入,正确的做法是在函数内部进行导入:

# In b.py:
def cause_a_to_do_something():
    import a
    a.do_something()

现在,a.py可以安全地执行import b而不会引发问题。

乍一看,cause_a_to_do_something()似乎会非常低效,因为每次调用它时都会进行一次import,但实际上,导入的工作只在第一次调用时进行。第二次及之后的调用导入模块时,这个操作会很快完成。

撰写回答