Python 个模块作为脚本

Python modules as scripts

我有一个依赖于模块的 python 程序。结构如下

program.py
modules/__init__.py
modules/mod1.py
modules/mod2.py
modules/utils.py

program.py 包括 modules/ 目录中的所有模块,modules/ 中的模块通过 from .utils import *

包括 modules/utils.py

以上在 运行 program.py 时工作正常。然而,mod1.pymod2.py 也作为它们自己的脚本工作,但是 运行 python mod1.py 给出了错误

from .utils import *
ModuleNotFoundError: No module named '__main__.utils'; '__main__' is not a package

从导入中删除 . 可以使各个脚本正常工作,但是主 program.py 脚本找不到 utils.

如何使主程序和各个模块的导入都起作用?

您可能会发现对您的程序进行单点访问会更好。如果这是一个命令行实用程序,您可以使用命令行解析器为所有功能创建一个包装器,例如内置 argparse, or an external library like click.

使用点击,您可以添加一个名为例如cli.py,并将其用作您的单一访问点,然后使用标志来访问程序的不同功能。使用 setuptools,您可以为您的程序创建一个干净的入口点。

所以你的文件结构变成:

|-__init__.py
|-program.py
|-cli.py
|-setuptools.py
|-modules
  |-mod1.py
  |-mod2.py
  |-utils.py

cli.py:

import click
import program

@click.group()
def cli():
    pass

@cli.command()
def program():
    program.run_the_program()

@cli.command()
def mod1():
    program.mod1.run_the_program()

@cli.command()
def mod2():
    program.mod2.run_the_program()

if __name__ == '__main__':
    cli()

还有你的setup.py:

from setuptools import setup

setup(
    name="your-program",
    version="1.0",
    py_modules=["program"],
    include_package_data=True,
    install_requires=["click"],
    entry_points="""
        [console_scripts]
        program=program:cli
    """,
)

在您的目录中创建一个 virtualenv,激活它,运行 setuptools pip install --editable,然后您应该能够 运行 您的程序或 mod1 和 mod2 子程序来自使用 program programprogram mod1 等的命令行