如何使一个软件包引用另一个软件包,但看起来像引用的软件包属于初始软件包?
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_2module_1.pyc'>
>>> from package_2 import module_1
>>> print module_1
<module 'package_2.module_1' from '...package_2module_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_1
下添加package_2.py
模块,该模块仅包含:
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
s中定义的内容,则会得到ImportError
。如果要避免这种情况,则可以:
使用特定的
import
s导入您需要的所有东西:from package_2 import * from package_2 import submodule1, submodule2, subpackage3
在
package_2
下添加一个_all.py
模块,该模块导入您想要暴露的所有内容并从该模块中导入
肯定会避免使用*
-Imports,但是在这种情况下, 似乎是解决问题的唯一解决方案,不需要黑客入侵导入机制。
如果您真的以另一种方式讨厌这一点,那就是使用导入钩子编写自定义进口商,但这需要大量工作才能使它正确。
另外,由于package_2
现在是其自己的软件包,因此您可能应该考虑弃用旧的导入方式,以便能够在以后的某些版本中删除此"黑客"。如果您将来要摆脱进口挂钩,那么花太多时间写一个进口挂钩可能是不值得的。
请注意,from
导入:
from package_1.package_2 import module1
需要您实际提供package_1.package_2
模块或子包。
表格的import
s:
from X.Y.Z import something
首先导入X
,然后进口商将在X
目录下搜索一个名为Y.py
的文件。然后,它将在X/Y
或目录X/Y/Z
下搜索Z.py
文件,最后,如果在导入的Z
模块中找到something
,则简单地放置在范围中,否则something
是导入的模块。
然而,最后一步,检查something
是否已经存在于Z
中,仅在所有X
,Y
和Z
都完全导入时才能执行。在您的用例中:
from package_1.package_2 import module1
您简单地不能在package_1
中仅定义package_2
。