[英]Packaging a Python library with an executable
I just finished a module and want to package it. 我刚刚完成一个模块,并希望将其打包。 I've read the documentation and this question packaging a python application but I am not sure about how to proceed when I don't have a package to import but a script to launch instead.
我已经阅读了文档和打包python应用程序的问题,但是当我没有要导入的包而是要启动的脚本时,我不确定如何继续。
The project looks like that: 该项目如下所示:
Project/
|-- README
|-- requirement.txt
|-- driver.py
|-- run.py
|-- module_1
| |-- __init__.py
| |-- class_1.py
| |-- class_2.py
|-- module 2
|-- |-- __init__.py
|-- |-- class_1.py
|-- |-- class_2.py
In order to launch the tool I do: 为了启动该工具,我要做的是:
python run.py arg1 --option arg2
driver.py
imports all other modules and defines a Driver
class and some functions. driver.py
导入所有其他模块,并定义一个Driver
类和一些函数。 run.py
imports driver.py
, parse arguments, setups the logger and calls the function one after the others to do the job. run.py
导入driver.py
,解析参数,设置记录器并driver.py
调用该函数以完成工作。
I'm not sure about the configuration of setup.py
, also do I need a global __init__.py
at the root? 我不确定
setup.py
的配置,也需要在根目录下使用全局__init__.py
吗? From what I've understand, I will only be able to do import Project
not to launch the script run.py
with its arguments. 据我了解,我将只能
import Project
而不启动带有参数的脚本run.py
From other readings, maybe I should try to tell that Driver.py
is the package and use the entry_points
option of setup()
. 从其他读物来看,也许我应该尝试说出
Driver.py
是软件包,并使用setup()
的entry_points
选项。 But I don't understand how to do all of it properly. 但是我不知道如何正确地完成所有这些工作。
Thank you for your kind help! 谢谢你的热心帮助!
Generally, you only distribute python packages as modules when the entire project fits in a single module file. 通常,仅当整个项目适合单个模块文件时,才将python软件包作为模块分发。 If your project is more complex than that, it's usually best to structure your project as a package with an
__init__.py
file. 如果您的项目比这更复杂,通常最好将项目构造为带有
__init__.py
文件的程序包。 Here is what your project would look like converted to a package 这是您的项目转换成包后的样子
Project/
|-- README
|-- requirement.txt
|-- setup.py
|-- scripts/
| |-- driver.py
|-- driver/
| |-- __init__.py
| |-- module_1
| | |-- __init__.py
| | |-- class_1.py
| | |-- class_2.py
| |-- module_2
| |-- |-- __init__.py
| |-- |-- class_1.py
| |-- |-- class_2.py
I renamed your run.py
to scripts/driver.py
and the code you previously had in driver.py
is now driver/__init__.py
. 我将您的
run.py
重命名为scripts/driver.py
,以前在driver.py
拥有的代码现在为driver/__init__.py
。
Your setup.py
should look like this 您的
setup.py
应该看起来像这样
from setuptools import setup. find_packages
setup(
name='driver',
version='1.0',
packages=find_packages(),
scripts=['scripts/driver.py'],
)
This will copy scripts/driver.py
to the python Scripts directory. 这会将
scripts/driver.py
复制到python Scripts目录。 I renamed run.py
to driver.py
since run
is pretty generic and you want your script names to be unique since all python packages share the same scripts location. 我改名
run.py
到driver.py
因为run
是非常通用的,你希望你的脚本名称是唯一的,因为所有Python包共享相同的脚本的位置。
Alternatively, you could use the console_scripts
entry point. 或者,您可以使用
console_scripts
入口点。 In this case, you wouldn't have a separate scripts/driver.py
script. 在这种情况下,您将没有单独的
scripts/driver.py
脚本。 Instead, you would just have a function inside your package. 取而代之的是,您的包中只有一个函数。 In this case, you could move all the code from
scripts/driver.py
into driver/command_line.py
and put it inside a function called main()
. 在这种情况下,您可以将所有代码从
scripts/driver.py
移到driver/command_line.py
并将其放入一个名为main()
的函数中。 Then change your setup.py
to this 然后将您的
setup.py
更改为此
setup(
name='driver',
version='1.0',
packages=find_packages(),
entry_points = {
'console_scripts': ['driver=driver.command_line:main'],
}
)
Also, you should read this docs page on python packaging . 另外,您应该阅读有关python Packaging的此文档页面 。 It covers the basics and a lot of the common use cases.
它涵盖了基础知识和许多常见用例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.