如何使一个包引用另一个包,但使其看起来像引用的包属于初始包?
package_1
|
|____ __init__.py
package_2
|
|____ __init__.py
|____ module_1.py
package_1.__init__.py里面是
# __init__.py
import package_2
现在以下调用可以正常工作:
>>> import package_1
>>> print package_1
<module <module 'package_1' from '...\package_1\__init__.pyc'>
>>> from package_1 import package_2
>>> print package_2
<module 'package_2' from '...\package_2\__init__.pyc'>
>>> print package_2.module_1
<module 'package_2.module_1' from '...\package_2\module_1.pyc'>
>>> from package_2 import module_1
>>> print module_1
<module 'package_2.module_1' from '...\package_2\module_1.pyc'>
但我希望能够做到这一点:
>>> from package_1.package_2 import module_1
但我得到:
Traceback (most recent call last):
File "testfile.py", line 15, in <module>
from package_1.package_2 import module_1
ImportError: No module named package_2
我想这样做的原因是package_2曾经是package_1的子包。现在 package_2 是它自己的包,我希望能够从 package_1 引用它以保持以前的行为。
最佳答案
您可以添加package_2.py
模块位于 package_1
它只包含:
from package_2 import *
如果您使用的是 python2,您应该添加:
from __future__ import absolute_import
位于文件顶部,以便具有 python3 的行为。
这样package_1.package_2
与package_2
不同 ,即:
import package_1.package_2
import package_2
print(package_2 is package_1.package2) #False
但是里面的所有对象 package_1.package_2
与外部模块相同。
这有一个限制,如果您想导入子模块,而不仅仅是 package_2/__init__.py
中定义的内容的,您会得到 ImportError
。如果您想避免这种情况,您可以:
使用特定的
import
导入您需要的所有内容:from package_2 import * from package_2 import submodule1, submodule2, subpackage3
添加
_all.py
模块位于package_2
导入您想要公开的所有内容并从中导入
当然*
-通常会避免导入,但在这种情况下,这似乎是解决问题的唯一解决方案,不需要破解导入机制。
如果你真的讨厌这个,我能想到的另一种方法是使用导入钩子(Hook)编写一个自定义导入器,但这需要相当多的工作才能做到正确。
此外,自 package_2
现在是它自己的包,您可能应该考虑弃用旧的导入方式,以便能够在将来的某个版本中删除此“黑客”。如果您将来打算摆脱它,那么花费太多时间编写导入钩子(Hook)可能是不值得的。
请注意 from
导入:
from package_1.package_2 import module1
要求您实际提供 package_1.package_2
模块或子包。
import
形式:
from X.Y.Z import something
首次导入X
,然后导入器将搜索名为 Y.py
的文件下X
目录。然后它会搜索 Z.py
文件位于X/Y
下或目录X/Y/Z
最后,如果something
在导入的Z
中找到module 它只是放置在范围内,否则 something
是一个导入的模块。
但是最后一步,检查是否 something
已存在于 Z
,仅在全部 X
时执行, Y
和Z
完全进口。在您的用例中:
from package_1.package_2 import module1
您根本不能拥有package_2
简单地在 package_1
中定义.
关于Python - 引用的包是其他包的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21562979/