问题描述
我刚完成一个模块并想打包它.我已经阅读了文档和这个问题包装python应用程序,但是我不确定如何当我没有要导入的软件包但要启动的脚本时继续执行.
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.
该项目如下所示:
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
导入所有其他模块,并定义Driver
类和某些函数. run.py
导入driver.py
,解析参数,设置记录器并依次调用该函数以完成工作.
driver.py
imports all other modules and defines a Driver
class and some functions. run.py
imports driver.py
, parse arguments, setups the logger and calls the function one after the others to do the job.
我不确定setup.py
的配置,我是否也需要在根目录下使用全局__init__.py
?据我了解,我将只能执行import Project
而不启动带有参数的脚本run.py
.
I'm not sure about the configuration of setup.py
, also do I need a global __init__.py
at the root? From what I've understand, I will only be able to do import Project
not to launch the script run.py
with its arguments.
从其他阅读材料来看,也许我应该尝试说出Driver.py
是程序包,并使用setup()
的entry_points
选项.但是我不知道如何正确地完成所有工作.
From other readings, maybe I should try to tell that Driver.py
is the package and use the entry_points
option of setup()
. But I don't understand how to do all of it properly.
谢谢您的帮助!
推荐答案
通常,仅当整个项目适合单个模块文件时,才将python软件包作为模块分发.如果您的项目比这更复杂,通常最好将项目构造为带有__init__.py
文件的程序包.这就是您的项目转换成包后的样子
Generally, you only distribute python packages as modules when the entire project fits in a single module file. If your project is more complex than that, it's usually best to structure your project as a package with an __init__.py
file. 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
我将您的run.py
重命名为scripts/driver.py
,您以前在driver.py
中拥有的代码现在是driver/__init__.py
.
I renamed your run.py
to scripts/driver.py
and the code you previously had in driver.py
is now driver/__init__.py
.
您的setup.py
应该看起来像这样
from setuptools import setup. find_packages
setup(
name='driver',
version='1.0',
packages=find_packages(),
scripts=['scripts/driver.py'],
)
这会将scripts/driver.py
复制到python Scripts目录.我将run.py
重命名为driver.py
,因为run
非常通用,并且您希望脚本名称唯一,因为所有python软件包都共享同一脚本位置.
This will copy scripts/driver.py
to the python Scripts directory. 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.
或者,您可以使用console_scripts
入口点.在这种情况下,您将没有单独的scripts/driver.py
脚本.取而代之的是,您的包中只有一个函数.在这种情况下,您可以将所有代码从scripts/driver.py
移到driver/command_line.py
并将其放入名为main()
的函数中.然后将您的setup.py
更改为此
Alternatively, you could use the console_scripts
entry point. In this case, you wouldn't have a separate scripts/driver.py
script. 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()
. Then change your setup.py
to this
setup(
name='driver',
version='1.0',
packages=find_packages(),
entry_points = {
'console_scripts': ['driver=driver.command_line:main'],
}
)
此外,您应该阅读关于python包装的此文档页面.它涵盖了基础知识和许多常见用例.
Also, you should read this docs page on python packaging. It covers the basics and a lot of the common use cases.
这篇关于用可执行文件打包Python库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!