Relative import problems in Python 3
python imports让我抓狂(我对python imports的经验有时根本不符合"explicit is better than implicit":():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [app] start.py from package1 import module1 [package1] __init__.py print('Init package1') module1.py print('Init package1.module1') from . import module2 module2.py print('Init package1.module2') import sys, pprint pprint.pprint(sys.modules) from . import module1 |
我得到:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | vic@ubuntu:~/Desktop/app2$ python3 start.py Init package1 Init package1.module1 Init package1.module2 {'__main__': <module '__main__' from 'start.py'>, ... 'package1': <module 'package1' from '/home/vic/Desktop/app2/package1/__init__.py'>, 'package1.module1': <module 'package1.module1' from '/home/vic/Desktop/app2/package1/module1.py'>, 'package1.module2': <module 'package1.module2' from '/home/vic/Desktop/app2/package1/module2.py'>, ... Traceback (most recent call last): File"start.py", line 3, in <module> from package1 import module1 File"/home/vic/Desktop/app2/package1/module1.py", line 3, in <module> from . import module2 File"/home/vic/Desktop/app2/package1/module2.py", line 5, in <module> from . import module1 ImportError: cannot import name module1 vic@ubuntu:~/Desktop/app2$ |
我正在使用python 3。
我需要循环进口。module1中的函数断言其参数之一是module2和viceversa中定义的类的实例。
换言之:
另外,
更新:
这项黑客工作(但我正在寻找"官方"方式):
1 2 3 4 5 6 7 8 | print('Init package1.module2') import sys, pprint pprint.pprint(sys.modules) #from . import module1 parent_module_name = __name__.rpartition('.')[0] module1 = sys.modules[parent_module_name + '.module1'] |
对于您的问题,一个更好的解决方案是将package1放入它自己的单独包中。当然,它不能导入包2,但是如果它是可重用的,为什么会这样呢?
一般来说,应该避免循环导入,另请参阅相关问题的答案或effbot.org上的这篇文章。
在这种情况下,问题是您导入了
如果您在
1 2 3 | print('Init package1') from . import module1 as m1 from . import module2 as m2 |
现在,当您在
如果您不明确地导入
为了使其有效,您可以在
或者更好的是,你完全摆脱了循环导入。如果您有循环引用,这通常意味着您的应用程序结构不太好。
(我希望我的解释有意义,我已经很难写了,但总的来说应该是清楚的,我希望…)
编辑为了响应您的更新,您要做的是使用完整的包名称来获取对模块的引用。这相当于(但要复杂得多)使其工作的第一个可能选项;使用绝对导入时使用的导入路径与
您的更新模拟了绝对导入的作用:如果您在导入
1 2 | import importlib module1 = importlib.import_module('.module1', __package__) |
I need circular imports. A function in module1 asserts that one of its
parameter is instance of a class defined in module2 and viceversa.
如果不想使用绝对导入,可以将类移到单独的模块中,以解决循环依赖关系,或者在函数级别进行导入。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | . ├── start.py # from package1 import module1 └── package1 ├── __init__.py # print("Init package1") # from . import module1, module2 ├── c1.py # print("Init package1.c1") # class C1: # pass ├── module1.py # print("Init package1.module1") # from .c1 import C1 # from .module2 import C2 └── module2.py # print("Init package1.module2") # from .c1 import C1 # class C2: # pass # def f(): # from .module1 import C1 |
产量
1 2 3 4 | Init package1 Init package1.module1 Init package1.c1 Init package1.module2 |
另一个比重构
1 2 | module2.py import module1 |
也工作。
确保您的
现在,编写以下代码-
1 2 | from .package1 import class1 class1.method1() |
这是我解决问题的方法。综上所述,您的根目录是
我今天也遇到了同样的问题,在python3.4中,这个问题似乎确实被打破了,但在python3.5中是有效的。
变更日志包含一个条目:
Circular imports involving relative imports are now supported. (Contributed by Brett Cannon and Antoine Pitrou in bpo-17636).
通过BugReport,看起来这并不是一个修复的buf,而是导入工作方式中的一个新特性。参考上文Poke的回答,他指出
Python中对循环导入依赖性的公认答案很重要:
If a depends on c and c depends on a, aren't they actually the same unit then?
You should really examine why you have split a and c into two packages, because either you have some code you should split off into another package (to make them both depend on that new package, but not each other), or you should merge them into one package.
— Lasse V. Karlsen?
也许您应该考虑将它们放在同一个模块中。:)