导入错误:不能两个文件之间导入名导入相同
我有这样的代码导入错误:不能两个文件之间导入名导入相同
mainModule
from src.comp.mypackage.wait import Wait
from src.comp.mypackage.men import Men, MenItem
""" Code and stuff using Men and MenItem """
if __name__ == '__main__':
MenuTestDrive.main()
男人
from abc import ABCMeta, abstractmethod
from src.comp.mypackage.util import NullUtil, CompUtil
UTIL
from src.comp.mypackage.stack import Stack
from src.comp.mypackage.men import Men
""" Code and stuff using Men and MenItem """
和运行mainModule时,我正在给这个错误:
Traceback (most recent call last):
File "/home/user/PycharmProjects/pythonProj/pythonDesignPatterns/src/comp/mypackage/mainModule.py", line 2, in <module>
from pythonDesignPatterns.src.comp.mypackage.men import Men, MenItem
File "/home/user/PycharmProjects/pythonProj/pythonDesignPatterns/src/comp/mypackage/men.py", line 2, in <module>
from pythonDesignPatterns.src.comp.mypackage.iterator import NullUtil, CompUtil
File "/home/user/PycharmProjects/pythonProj/pythonDesignPatterns/src/comp/mypackage/util.py", line 2, in <module>
from pythonDesignPatterns.src.comp.mypackage.men import Men
ImportError: cannot import name 'Men'
我使用pyCharm,但错误在命令行是一样的。
我可以提供更多的代码,但我不认为有任何使用类的幻想,只会分散注意力。
我应该在哪里寻找失败?
TL; DR:蟒蛇不允许圆形进口,所以你不能有模块men
从模块util
进口,如果模块util
进口模块men
。
较长的答案:
你要明白,在Python import
,class
,def
等其实都是可执行语句和一切(或几乎)发生在运行时。在给定进程中首次导入模块时,所有顶级语句都将按顺序执行,将创建一个module
实例对象,并将所有顶级名称作为属性(请注意,class
,def
和import
都绑定了名称)并插入到sys.modules
缓存字典中,以便相同模块的下一个导入将直接从缓存中检索。
在你的情况下,首先导入时,该men
模块试图导入util
模块,这是不是在sys.modules
却又如此Python运行时所处的util.py(或.pyc文件)文件并执行它。然后它到达from src.comp.mypackage.men import Men
。此时,men.py
尚未完全执行,因此没有Men
属性。
规范的解决方案是将循环依赖提取到第三个模块中,或者将两个模块合并为一个模块,具体取决于一个对您的具体情况有意义的事情(目标是一如既往地让模块具有低耦合和高凝聚力)。 FWIW,即使语言支持它们,循环依赖也被认为是不好的设计。
有时(大多数情况下,在复杂的框架中,将某些特定结构强加给您的代码和特定的导入顺序),最终可能会出现循环依赖链或者更复杂(如A.funcX依赖于By,B取决于依赖于D的C,它依赖于最终依赖于A.funcZ的E)和/或非常难以以有意义的方式干净地重构。作为最后的手段,您仍然可以在函数中推迟一些导入语句(在上面它将在A.funcX
之内)。这是仍然认为是一种不好的做法,应该只能作为最后的手段使用。
作为便笺:从您的软件包命名方案我可以闻到强大的Java影响力。 Python不是Java!不是说Java有什么问题,它只是these are two wildly different languages和wildly different designs, idioms and philosopies。
试图在Python中强制使用Java习语和习惯最好是在痛苦和沮丧的经历(这里已经完成了......),所以我的建议是:忘记你学习Java的大部分内容,开始学习Python(而不仅仅是语法 - 语法实际上只是语言的一部分,不一定是最重要的语法)。在Python中,我们倾向于平面嵌套,并且不要尝试为每个类使用一个模块,您可以在一个模块中包含整个(微)框架,如果没有实际的理由将其分解为子模块,那也没关系。
这是一个从Java翻译而来的设计模式源代码,但总的来说,我将模型类似的对象分组,并且在它们不配合任何对象(如Java接口)等时合并对象。但是对于这些模式,一些Java设计依赖于。无论如何感谢您的建议,这是一个很好的建议 – madtyn
名字'男人'真的存在'男人'包?你能否在你的问题中提供它的定义? – Grigoriy