Python - 引用的包是其他包的属性

标签 python import package relative-import

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

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_2package_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 时执行, YZ完全进口。在您的用例中:

from package_1.package_2 import module1

您根本不能拥有package_2简单地在 package_1 中定义.

关于Python - 引用的包是其他包的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21562979/

相关文章:

python - 应该如何编写 Python 文件,使其既可以是模块又可以是具有命令行选项和管道功能的脚本?

node.js - 使用 SQLite3 包的 Node.js 脚本中的查询顺序错误

python XML 获取 <p>...</p> 标签内的文本

python - 我如何在基于 django 类的 api View 中调用自己的方法

c++ - std::cin 适用于少量行,但不适用于较大行

html - CSS @import 是否导致遗漏文件扩展名?

python - 使用 PyAudio 获取运行机速度

python - pylint 禁用单行代码只会产生另一个 pylint 错误

java - 动态获取java包中实现接口(interface)的每个类

deployment - 标准 "Installation"实际上做了什么?