我正在研究由许多脚本组成的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:没有名为“实用程序”的模块
而
python my_module --help
没有问题
python my_module
和python -m my_module
都起作用的方式构造导入。import my_module
(奖励)在没有由python
首先调用./my_module --help
解释器的情况下运行。我不确定如何使用tree:
|-- my_module
| |-- my_module.py
| |-- __init__.py
| |-- __main__.py
| |-- module_component_A.py
| |-- utilities.py
是否有应转到my_module.py
的特定内容?
答案 0 :(得分:3)
Python 3没有隐含的相对导入。使用绝对或显式相对导入:
from .utilities import check_directory_access
from my_module.utilities import check_directory_access
这使您的程序包可以与-m
开关一起使用。它还允许在交互式会话中使用import my_module
。
存储为文件夹的裸包无法直接执行。这是由于操作系统本身。如果要避免显式调用python,则必须创建一个运行程序包的可执行文件。
要么将软件包存储为可执行zip文件,要么创建运行您的软件包的脚本。
#!/usr/bin/env python3
import my_module.__main__
请注意,后面的版本要求您安装模块或直接将其与脚本相邻。
您不应将脚本驻留在软件包中-这要求您将sys.path
更改为父目录,这可能导致重复的模块。例如,utilities.py
将作为单独的模块my_module.utilities
和 utilities
可用。