python - 从父包导入模块
问题描述
我有一个如下结构:
package/
setup.py
...
package/
__init__.py
_foo.py
subpackage/
__init__.py
bar.py
我正在尝试_foo
从内部导入bar
:
# bar.py
from .._foo import baz
def myfunc():
baz()
# stuff
在bar.py
作为脚本运行时(例如,在 Jupyter Notebook 中,甚至python bar.py
使用python -m package.subpackage.bar
. 我无法让它工作:
>>> from . import _foo
ImportError: cannot import name '_foo' from '__main__' (unknown location)
# changing __name__ to 'package' doesn't work etiher
>>> from ._foo import baz
ModuleNotFoundError: No module named '__main__._foo'; '__main__' is not a package
>>> from .. import _foo
ValueError: attempted relative import beyond top-level package
>>> sys.path.append(os.getcwd())
>>> from .._foo import baz
ValueError: attempted relative import beyond top-level package
>>> from ._foo import baz
ModuleNotFoundError: No module named 'package'
我打算将其发布以供公众使用,因此仅适用于我的机器的技巧对我来说并不真正有用(指的是我发现的一些sys.path
技巧PYTHONPATH
)。
解决方案
Python 不支持从包中运行脚本,因为Guido 认为这是一种反模式。
现有的解决方案是将 bar 作为一个模块运行:
python -m package.subpackage.bar
或创建一个console_scripts
入口点:
# in setup.py
from setuptools import setup
setup(
...
entry_points={
"console_scripts": [
"mybarscript=package.subpackage.bar:myfunc",
]
}
)
package
安装后,将自动生成一个名为的 Python脚本mybarscript
。它将挂钩myfunc
到bar.py
.
推荐阅读
- php - PHP将多维数组键转换为数组多维值
- swift - 如何每秒将 SKShapeNode 的半径增加 1 个像素?
- python - 在单个 cmd 中运行多个命令有一些延迟
- delphi - Delphi Spring Mocking:“as”操作中的无效转换——我该如何解决这个问题?
- php - 如何组合两个数组,一个作为键,另一个作为数组?
- c# - 抽象参数和方法初学者
- doxygen - 如何在 doxygen 的示例页面下显示源代码
- vba - VBA 从一个单元格中查找值并将所有值粘贴到另一个单元格
- c++ - 尝试在 C++ 中打印前 10 个偶数自然数
- php - CI 3 没有从 ajax 接收任何数据,尽管它触发了成功