【问题标题】:Python - access module from package that is not imported through __init__.py?Python - 从未通过 __init__.py 导入的包中访问模块?
【发布时间】:2019-05-29 07:05:00
【问题描述】:

我正在使用一个带有__init__.py 的包仅从模块导入一个变量,但整个模块本身并未暴露。有没有办法访问那个模块?

让我们看看这个案例:

整包:

test_package/
├── __init__.py
└── test_me.py

现在内容:

__init__.py

from .test_me import test_me

test_me.py

STATIC = 'static'


class Test:
    pass


test_me = Test()

现在如果我导入包test_package。我只能访问变量test_me,它是Test 类的一个实例。虽然我无法访问STATIC 变量,因为模块本身没有暴露出来。

在这种情况下,有没有办法访问test_me 模块,而不仅仅是其中一个变量?

附:如果我使用sys 将路径直接附加到该包的模块,当我尝试导入它时会抛出该模块不存在的错误。

【问题讨论】:

  • 你到底想做什么?你想在import test_package之后访问test_package.STATIC吗?
  • @feliks 是的,在我的真实情况下,我需要使用该模块内的函数。例如,我想要 STATIC 变量。想法是 su 访问其他属性而不是被暴露。举个例子。

标签: python python-3.x python-import name-collision


【解决方案1】:

如果将包目录添加到路径中,Python 可以导入该目录中的任何文件,就好像它本身是一个模块一样。

import sys
sys.path.extend(test_package.__path__)
import test_me
print(test_me.STATIC)

【讨论】:

  • 似乎不起作用(或者我错过了什么?)。如果我完全按照你的描述做,那么我会得到NameError: name 'test_package' is not defined。如果我首先正常导入test_package,然后尝试按照你的方式做,那么当我尝试做import test_me时,我得到ImportError: No module named 'test_me'
  • @Andrius 我测试了它,它对我有用。您的测试设置是否与问题中显示的一样完全?您使用的是哪个版本的 Python?
  • 嗯,我复制粘贴的内容,所以应该是一样的。 Python 3
  • @Andrius 抱歉,我在测试时使用了硬编码路径。我没有意识到 test_package.__path__ 是一个列表而不是一个字符串。我已经更新了答案。
【解决方案2】:

需要通过__init__.py导入,所以将其内容改为:

from .test_me import test_me, STATIC

现在以下将起作用:

import test_package
print(test_package.STATIC)

【讨论】:

  • 当然可以。我知道。问题是如果没有导入它如何访问它。如果它甚至可能?这个包不是我的,所以我不能修改它。或者我需要分叉该项目并对其进行自定义。我不想这样做。
猜你喜欢
  • 1970-01-01
  • 2013-04-21
  • 2018-10-27
  • 2013-07-29
  • 2015-07-30
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
  • 2016-06-14
相关资源
最近更新 更多