python-引用的软件包是其他软件包的属性



如何使一个软件包引用另一个软件包,但看起来像引用的软件包属于初始软件包?

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中,仅在所有XYZ都完全导入时才能执行。在您的用例中:

from package_1.package_2 import module1

您简单地不能在package_1中仅定义package_2

最新更新