python -m 并在 __init__.py 中导入

python -m and imports in __init__.py

我有一个 python 包,结构如下

|-- a
    |-- b
        |-- c
           |-- dummy.py

其中 a、b、c 是文件夹/子包,都具有各自的 __init__.py。 现在我当然可以从命令行调用 dummy.py 作为脚本,例如 python -m a.b.c.dummy 但我想在顶层 别名 __init__.py这样我就可以在写

时做 python -m a.do_this
# __init__.py of a
from a.b.c import dummy as do_this

不幸的是,我得到“没有名为 do_this 的模块”这当然是真的,但是没有办法使这个 别名 吗?由于实施原因,我想保留文件夹结构,但想让用户轻松使用。

除了您可能不想使用模块加载作为启动脚本之外,您可以通过这样的树获得 python -m a.do_this 行为:

.
└── a
    ├── b
    │   ├── c
    │   │   ├── dummy.py
    │   │   └── __init__.py
    │   └── __init__.py
    ├── do_this.py
    └── __init__.py

假设 a/b/c/dummy.py 包含:

print("foo")

以及您在 a/do_this.py 中的导入行:

from a.b.c import dummy

这符合您的要求,但我想这可能不是您想要的。

$ python -m a.do_this
foo

无论如何,我会推荐@chepner 在评论中建议的方式,使用适当的 python 包 setup.py 并定义 console_scripts 部分。

你的第一个虽然不起作用的原因是,你试图用 -m 加载一个模块,但你在 __init__.py 中的语句不构成一个模块。

设置工具文档 https://setuptools.readthedocs.io/en/latest/userguide/entry_point.html 回答它。很好用。