gpt4 book ai didi

python - 构建 python 模块,以便它可以从带有和不带 -m 开关的命令行运行

转载 作者:太空宇宙 更新时间:2023-11-03 23:59:17 24 4
gpt4 key购买 nike

背景

我正在研究由许多脚本组成的 Python 模块。最终目标是在交互式工作时通过 import 语句使该模块中的函数可导入,并通过命令行参数使模块的某些部分可执行。

期望的结果

模块可以使用:

python -m ./my_module --help
# No -m switch
python ./my_module --help

结构

正在关注 this answer我想了解 -m 开关与 __main__.py__init__.py 文件的关系。当前结构如下

__main__.py

# Shebang line


###########
# Modules #
###########
import argparse
import logging
import tempfile


###################
# Package modules #
###################
from utilities import check_directory_access
# ...


#################
# Run functions #
#################
def run(args):
"""Run all functions with provided arguments"""
# Start logging configuration
# If file is not provided use temporary file
if args.log_file is None:
args.log_file = tempfile.NamedTemporaryFile(delete=False,
prefix='my_module',
suffix='.log').name
# Create handlers: console
# logging configuration
logging.shutdown()


def main():
"""Process arguments and run main function"""
parser = argparse.ArgumentParser(description='Dop stuff module',
epilog='Epilog')
parser.add_argument("-t", "--tables", nargs='+', dest='tables',
help="List tables to refresh", type=str)
parser.add_argument("-l", "--log-file", dest='log_file',
type=str, help="Log file")
parser.set_defaults(func=run)
args = parser.parse_args()
args.func(args)

if __name__ == "__main__":
main()

__init__.py

###################
# Package modules #
###################
from .utilities import check_directory_access
# Other components

问题

运行:

python -m my_module --help

返回

ImportError: No module named 'utilities'

鉴于

python my_module --help

没有问题

期望的结果

  • 以语句 python my_modulepython -m my_module 都有效的方式构建导入。
  • 在交互工作时不破坏import my_module
  • (奖励) 无需先通过 ./my_module --help 调用 python 解释器即可运行。我不确定如何用树来做:

    |-- my_module
    | |-- my_module.py
    | |-- __init__.py
    | |-- __main__.py
    | |-- module_component_A.py
    | |-- utilities.py

    my_module.py 是否有特定内容?

最佳答案

Python 3 没有隐含的相对导入。使用绝对或显式相对导入:

from .utilities import check_directory_access
from my_module.utilities import check_directory_access

这使您的包可以使用 -m 开关。它还允许在交互式 session 中import my_module


作为文件夹存储的裸包不能直接执行。这是由于操作系统本身。如果您希望避免显式调用 python,则必须创建一个运行您的包的可执行文件。

要么将包存储为可执行的 zip 文件,要么创建一个运行包的脚本。

#!/usr/bin/env python3
import my_module.__main__

请注意,后者需要安装您的模块或直接与您的脚本相邻。如果您的模块可以安装,一个 console_scripts entry_point允许自动创建这样的脚本。

你不应该让脚本驻留在你的包中 - 这需要你将 sys.path 更改为父目录,这可能会导致重复的模块。例如,utilities.py 将作为单独的模块 my_module.utilities utilities 提供。

关于python - 构建 python 模块,以便它可以从带有和不带 -m 开关的命令行运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56278550/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com