从父包导入模块

时间:2018-12-28 20:41:03

标签: python python-3.x import

我的结构如下:

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.pathPYTHONPATH技巧)。

1 个答案:

答案 0 :(得分:3)

Python不支持从包内运行脚本,因为Guido considered that an antipattern

现有的解决方案以模块的形式运行:

python -m package.subpackage.bar

或创建一个console_scripts entrypoint

# in setup.py
from setuptools import setup

setup(
    ...
    entry_points={
        "console_scripts": [
            "mybarscript=package.subpackage.bar:myfunc",
        ]
    }
)

安装package后,将自动生成一个名为mybarscript的Python脚本。它将挂接到myfunc中定义的可调用bar.py中。