如何在控制台中将 Python 项目打包为 运行
How to package a Python project to be run in the console
我在 Python 中编写了一个使用多个脚本(模块)的项目。主脚本调用其他模块并从文件夹中读取一些文件以执行其功能。
我正在尝试打包分发。我希望使它成为一个可从命令行运行的程序,这意味着,一旦用户下载并安装了它,他们就可以像这样调用该程序:
$ python my_program -i arg1 -o arg2
或类似。
我在网上找到的教程将项目以包的形式打包,您可以导入。
>> import my_program
>> my_program.run_stuff(arg1, arg2)
那不是我想要的。
既然你写了“或类似的”,假设你想这样调用程序:
$ my_program -i arg1 -o arg2
这个更短。这也是我们如何称呼无处不在的 Python 工具,例如 pip
。并且有一个既定的程序来为任何 Python 包定义一个“入口点”(众所周知)。
所有 Python 打包工具都允许这样做。我们可以 use the classic Setuptools if we wanted to — that's what Pip does. Or use Poetry, a more modern alternative. But it's often easiest to set up with Flit.
在最简单的情况下,您的程序包 my_program
仅包含一个 __init__.py
定义函数的文件:
def main():
print('Running my program...')
该函数通常作用于 sys.argv
中的命令行参数。函数不一定要叫main
,可以是任何名称,也可以在包的任何其他模块中。
然后我们可以在项目的元数据中定义控制台脚本的入口点。 Flit 从根文件夹中名为 pyproject.toml
的配置文件中读取。所以存储库现在看起来像这样:
.
├── my_program
│ └── __init__.py
└── pyproject.toml
使用元数据的最新标准,PEP 621、pyproject.toml
将包含:
[project]
name = 'my_program'
version = '1.0.0'
description = 'Can be run in the console from anywhere.'
[project.scripts]
my_program = 'my_program:main'
[build-system]
requires = ['flit_core>=3.2,<4']
build-backend = 'flit_core.buildapi'
在 [project.scripts
] section 中,我们已将控制台命令 my_program
映射到 my_program
包的顶级名称 space 中的 main
函数.同样,它也可以是包中其他地方的任何其他函数。
现在我们打包项目:
$ flit build --format wheel
Copying package file(s) from my_program I-flit_core.wheel
Writing metadata files I-flit_core.wheel
Writing the record of files I-flit_core.wheel
Built wheel: dist\my_program-1.0.0-py2.py3-none-any.whl I-flit_core.wheel
这会将打包的“wheel”放入名为 dist
的文件夹中。我们可以将该 .whl
文件上传到 PyPI 进行分发,或者立即使用 Pip 安装它:
$ pip install dist/my_program-1.0.0-py2.py3-none-any.whl
Processing .\dist\my_program-1.0.0-py2.py3-none-any.whl
Installing collected packages: my-program
Successfully installed my-program-1.0.0
现在我们可以 运行 程序像任何其他控制台应用程序一样:
$ my_program
Running my program...
Pip 为我们做的是,它在它自己的启动器旁边为我们的包创建了一个小启动器。就像 for Flit 一样。例如,在 Windows 上,Python 的 Scripts
文件夹中现在有一个 my_program.exe
,就在 pip.exe
和 flit.exe
旁边。
我在 Python 中编写了一个使用多个脚本(模块)的项目。主脚本调用其他模块并从文件夹中读取一些文件以执行其功能。
我正在尝试打包分发。我希望使它成为一个可从命令行运行的程序,这意味着,一旦用户下载并安装了它,他们就可以像这样调用该程序:
$ python my_program -i arg1 -o arg2
或类似。
我在网上找到的教程将项目以包的形式打包,您可以导入。
>> import my_program
>> my_program.run_stuff(arg1, arg2)
那不是我想要的。
既然你写了“或类似的”,假设你想这样调用程序:
$ my_program -i arg1 -o arg2
这个更短。这也是我们如何称呼无处不在的 Python 工具,例如 pip
。并且有一个既定的程序来为任何 Python 包定义一个“入口点”(众所周知)。
所有 Python 打包工具都允许这样做。我们可以 use the classic Setuptools if we wanted to — that's what Pip does. Or use Poetry, a more modern alternative. But it's often easiest to set up with Flit.
在最简单的情况下,您的程序包 my_program
仅包含一个 __init__.py
定义函数的文件:
def main():
print('Running my program...')
该函数通常作用于 sys.argv
中的命令行参数。函数不一定要叫main
,可以是任何名称,也可以在包的任何其他模块中。
然后我们可以在项目的元数据中定义控制台脚本的入口点。 Flit 从根文件夹中名为 pyproject.toml
的配置文件中读取。所以存储库现在看起来像这样:
.
├── my_program
│ └── __init__.py
└── pyproject.toml
使用元数据的最新标准,PEP 621、pyproject.toml
将包含:
[project]
name = 'my_program'
version = '1.0.0'
description = 'Can be run in the console from anywhere.'
[project.scripts]
my_program = 'my_program:main'
[build-system]
requires = ['flit_core>=3.2,<4']
build-backend = 'flit_core.buildapi'
在 [project.scripts
] section 中,我们已将控制台命令 my_program
映射到 my_program
包的顶级名称 space 中的 main
函数.同样,它也可以是包中其他地方的任何其他函数。
现在我们打包项目:
$ flit build --format wheel
Copying package file(s) from my_program I-flit_core.wheel
Writing metadata files I-flit_core.wheel
Writing the record of files I-flit_core.wheel
Built wheel: dist\my_program-1.0.0-py2.py3-none-any.whl I-flit_core.wheel
这会将打包的“wheel”放入名为 dist
的文件夹中。我们可以将该 .whl
文件上传到 PyPI 进行分发,或者立即使用 Pip 安装它:
$ pip install dist/my_program-1.0.0-py2.py3-none-any.whl
Processing .\dist\my_program-1.0.0-py2.py3-none-any.whl
Installing collected packages: my-program
Successfully installed my-program-1.0.0
现在我们可以 运行 程序像任何其他控制台应用程序一样:
$ my_program
Running my program...
Pip 为我们做的是,它在它自己的启动器旁边为我们的包创建了一个小启动器。就像 for Flit 一样。例如,在 Windows 上,Python 的 Scripts
文件夹中现在有一个 my_program.exe
,就在 pip.exe
和 flit.exe
旁边。