如何将模块用作包的一部分并作为可直接执行的脚本?
How to use a module as part of a package and as a directly executable script?
假设我有一个名为 my_package
的包文件夹。该目录包含一个名为 __init__.py
的文件和一个名为 my_module.py
的模块文件以及其他模块文件。模块 my_module.py
包含函数 do_something_with_file(file_path)
.
该函数在包的其他部分使用,但如果它可以作为命令行脚本调用,它将文件路径作为第一个位置参数并执行该函数,这将是实用的。我第一个天真的方法是通过以下方式实现:
if __name__ == "__main__":
import sys
do_something_with_file(sys.argv[1])
在 my_module.py
文件中。
但这需要 my_module.py
作为 main 执行。但作为包的一部分,它使用相对导入,只有当模块作为包的一部分执行时才有效,但如果脚本直接执行则失败,这使得这种方法没有吸引力。似乎此文件中的主块不是获得所需功能的正确方法。
将功能公开为简单脚本的最佳做法是什么?
我没有使用 python 打包的经验,我通常通过执行 python my_script.py
直接使用脚本,但我想更好地理解包和公开功能 with/via包。
如果您愿意公开一大堆模块以通过命令行使用,也许您可以创建一个 python 脚本,该脚本根据接收到的参数有条件地导入每个模块,而不必必须将 if __name__ == "__main__"
部分添加到它们中的每一个,以便您有一个脚本来调用多个模块。
如果您使软件包可安装,则公开脚本入口点效果最佳。我将尝试使用 python 本身附带的基本工具来提供一种或多或少的最小方法来做到这一点,并在最后列出一些第三方软件包,如果您有的话,它们会使整个过程更加愉快维护一段时间或者再写几个脚本。
要使用 setuptools
将您的代码转换为可安装的程序包,并使代码中的特定功能成为外部可执行脚本,请将 setup.py
文件添加到目录的顶层,像这样:
my_project
├───setup.py # right here, next to your source-code folder
└───my_package
├───__init__.py
└───my_module.py
setup.py
的内容至少是这样(检查 here 以了解更多可能对您的项目有意义或可能没有意义的关键字):
import setuptools
setuptools.setup(
name="my_package", # your choice, but usually same as the package
version="0.1.0", # obligatory
packages=["my_package"], # name of the folder relative to this file where the source code lives
install_requires=[], # your dependencies, if you have any
entry_points = { # this here is the magic that binds your function into a callable script
'console_scripts': ['my_script=my_package.my_module:do_something_with_file'],
}
)
entry_points
与 'console_scripts'
键结合使用的格式是:
['my_script=my_package.my_module:do_something_with_file']
| | | └─ this is essentially just a slightly reformatted import of
| | | 'from my_package.my_module import do_something_with_file'
| | └─ this sign starts the parsing of the lookup string for the bound function
| └─ the name you want to call your script by, can be chosen freely
└─ a list, since you can install multiple scripts with a single package
一旦你的设置就位,你 运行 pip install -e .
在它旁边。现在你的代码作为一个包被安装,你的函数被绑定为一个脚本。 运行 my_script location/to/some/file.txt
从您的控制台到 运行 do_something_with_file
with 'location/to/some/file.txt'
in sys.argv[1]
.
使脚本编写更容易的流行第三方库是 click (quite old, but therefore super solid, and what I'd usually recommend) and typer(更现代,利用最近的内置 python 功能,如类型注释)。
假设我有一个名为 my_package
的包文件夹。该目录包含一个名为 __init__.py
的文件和一个名为 my_module.py
的模块文件以及其他模块文件。模块 my_module.py
包含函数 do_something_with_file(file_path)
.
该函数在包的其他部分使用,但如果它可以作为命令行脚本调用,它将文件路径作为第一个位置参数并执行该函数,这将是实用的。我第一个天真的方法是通过以下方式实现:
if __name__ == "__main__":
import sys
do_something_with_file(sys.argv[1])
在 my_module.py
文件中。
但这需要 my_module.py
作为 main 执行。但作为包的一部分,它使用相对导入,只有当模块作为包的一部分执行时才有效,但如果脚本直接执行则失败,这使得这种方法没有吸引力。似乎此文件中的主块不是获得所需功能的正确方法。
将功能公开为简单脚本的最佳做法是什么?
我没有使用 python 打包的经验,我通常通过执行 python my_script.py
直接使用脚本,但我想更好地理解包和公开功能 with/via包。
如果您愿意公开一大堆模块以通过命令行使用,也许您可以创建一个 python 脚本,该脚本根据接收到的参数有条件地导入每个模块,而不必必须将 if __name__ == "__main__"
部分添加到它们中的每一个,以便您有一个脚本来调用多个模块。
如果您使软件包可安装,则公开脚本入口点效果最佳。我将尝试使用 python 本身附带的基本工具来提供一种或多或少的最小方法来做到这一点,并在最后列出一些第三方软件包,如果您有的话,它们会使整个过程更加愉快维护一段时间或者再写几个脚本。
要使用 setuptools
将您的代码转换为可安装的程序包,并使代码中的特定功能成为外部可执行脚本,请将 setup.py
文件添加到目录的顶层,像这样:
my_project
├───setup.py # right here, next to your source-code folder
└───my_package
├───__init__.py
└───my_module.py
setup.py
的内容至少是这样(检查 here 以了解更多可能对您的项目有意义或可能没有意义的关键字):
import setuptools
setuptools.setup(
name="my_package", # your choice, but usually same as the package
version="0.1.0", # obligatory
packages=["my_package"], # name of the folder relative to this file where the source code lives
install_requires=[], # your dependencies, if you have any
entry_points = { # this here is the magic that binds your function into a callable script
'console_scripts': ['my_script=my_package.my_module:do_something_with_file'],
}
)
entry_points
与 'console_scripts'
键结合使用的格式是:
['my_script=my_package.my_module:do_something_with_file']
| | | └─ this is essentially just a slightly reformatted import of
| | | 'from my_package.my_module import do_something_with_file'
| | └─ this sign starts the parsing of the lookup string for the bound function
| └─ the name you want to call your script by, can be chosen freely
└─ a list, since you can install multiple scripts with a single package
一旦你的设置就位,你 运行 pip install -e .
在它旁边。现在你的代码作为一个包被安装,你的函数被绑定为一个脚本。 运行 my_script location/to/some/file.txt
从您的控制台到 运行 do_something_with_file
with 'location/to/some/file.txt'
in sys.argv[1]
.
使脚本编写更容易的流行第三方库是 click (quite old, but therefore super solid, and what I'd usually recommend) and typer(更现代,利用最近的内置 python 功能,如类型注释)。