我有两个python模块:
A.Py
1 2 3 4 5 6 7 8
| import b
def hello():
print"hello"
print"a.py"
print hello()
print b.hi() |
B.Py
1 2 3 4
| import a
def hi():
print"hi" |
当我运行a.py时,我得到:
1
| AttributeError: 'module' object has no attribute 'hi' |
错误是什么意思?我该怎么修?
- 这是个糟糕的设计。为什么b.py在不引用a.py的任何部分时导入a?你在问如何解决这个问题吗?stackoverflow.com/search?Q=%5Bpython%5D+循环+依赖项
- 请注意,您的问题与此答案非常相似。显然,这个答案中的代码只是找到了,但你的代码没有找到?stackoverflow.com/a/7336880/565879
你们有相互的顶级进口,这几乎总是一个坏主意。
如果您确实必须在python中进行相互导入,那么方法是在函数中导入它们:
1 2 3 4
| # In b.py:
def cause_a_to_do_something():
import a
a.do_something() |
现在a.py可以安全地执行import b,而不会造成问题。
(乍一看,cause_a_to_do_something()似乎效率极低,因为它每次调用时都执行import,但实际上,导入工作只在第一次完成。第二次和以后导入模块时,这是一个快速操作。)
- 谢谢您!我第一次知道在不同的地方进口会产生如此大的差异。
- 请注意,当调用函数时,这会在头上增加,因为您将导入逻辑放在函数调用时,而不是程序加载时。
- 有趣;我想知道在这种情况下,为什么解释程序没有给出正确的错误消息?
我在无意中用与标准Python模块之一相同的名称命名模块时也看到了这个错误。例如,我有一个名为commands的模块,它也是一个python库模块。事实证明,这很难跟踪,因为它在我的本地开发环境中工作正常,但在Google应用程序引擎上运行时由于指定的错误而失败。
- 这就是解决我问题的答案。
- 我用abc.py编写了一个测试来演示python中的导入行为,这让我非常痛苦…
- 我怀疑这一点并删除了.py模块,但忘记删除仍然导致错误的.pyc。
- 我创建了一个数学模块,它已经是标准模块了。
问题是模块之间的循环依赖关系。a进口b和b进口a。但其中一个需要先加载——在这种情况下,python最终会在b之前初始化模块a,当您尝试在a中访问它时,b.hi()还不存在。
- 谢谢您!这是我的猜测。但我找不到文件提到它。如果我确实需要两个模块互相导入一些属性,我应该怎么做?
- @史蒂芬:打破循环依赖很容易。已经问了好几次了。stackoverflow.com/search?Q=%5Bpython%5D+循环+依赖项
- @洛特:谢谢。我只知道这是一个循环依赖性问题。
我通过引用以错误方式导入的枚举获得此错误,例如:
1 2 3 4
| from package import MyEnumClass
# ...
# in some method:
return MyEnumClass.Member |
正确进口:
1
| from package.MyEnumClass import MyEnumClass |
希望能帮助别人
我遇到了这个错误,因为模块实际上没有导入。代码如下:
1 2 3 4 5 6 7
| import a.b, a.c
# ...
something(a.b)
something(a.c)
something(a.d) # My addition, which failed. |
最后一行结果是一个AttributeError。原因是我没有注意到a的子模块(a.b和a.c是明确导入的,并且假定import的声明实际上是导入a的。
当我从Git签出一个旧版本的存储库时,遇到了这个问题。Git替换了我的.py文件,但留下了未跟踪的.pyc文件。由于.py文件和.pyc文件不同步,.py文件中的import命令在.pyc文件中找不到相应的模块。
解决方案只是删除.pyc文件,并让它们自动重新生成。
- 您可以使用此命令删除所有.pyc文件:find . -name"*.pyc" -exec rm -f {} \;。
以上的答案都很好,但我想在这里补充一下。如果您没有发现上述任何问题,请尝试清理您的工作环境。这对我很有用。
循环导入会造成问题,但python有办法减轻它的内置性。
问题是,当运行python a.py时,它运行a.py但不将其标记为作为模块导入。因此,依次为a.py->imports module b->imports module a->imports module b,自b当前正在导入以来,最后一次导入a no op,python对此进行了防范。B现在是一个空模块。所以当它执行b.hi()时,它找不到任何东西。
注意,执行的b.hi()是在a.py->模块B->模块A期间执行的,而不是直接在a.py中执行的。
在您的具体示例中,您可以在顶层运行python -c 'import a',因此,a.py的第一次执行注册为导入模块。
不确定是如何排序的,但下面的更改对我的问题进行了排序:
我的文件名和导入名相同,例如我的文件名为emoji.py,我试图导入emoji。但是更改文件名解决了这个问题。
希望如此有帮助