分发Python应用程序
我有一个简单的Python应用程序,它的文件夹结构如下:
- 项目/
- main.py
- config.py
- 插件/
- 插件1
- 插件2
- ...
config.py这个文件只是用来加载配置文件,里面并不包含任何配置的信息。
现在我想把这个程序分发出去,我想用setuptools来实现。用户需要使用的文件是main.py,所以这个文件应该放在/usr/bin目录下,而其他的文件则放在/usr/share/project目录下。
但有一个问题:我需要让main.py知道去share目录找config.py。但是我不太确定share目录具体在哪里,因为这取决于setuptools,对吧?
在分发基于Python的应用程序时,最佳的做法是什么?
1 个回答
setuptools 会把你的包安装到 Python 能找到的地方,也就是说你可以导入它:
import project
问题出现在你使用相对导入而不是绝对导入的时候。如果你的 main.py
导入了 config.py
,那是可以的,因为它们在同一个文件夹里。但是当你把 main.py
移到其他地方,比如 /usr/bin
或者其他在 PATH 环境变量中的位置时,Python 会尝试从 sys.path
导入 config.py
,而不是从你的包目录中导入。解决办法是使用绝对导入:
from project import config
这样 main.py
就可以“移动”了。
还有一种我更喜欢的解决方案是使用 setuptools 提供的自动脚本创建功能。
与其把你的代码放在一个
if __name__ == "__main__":
# here all your beautiful code
语句里,不如把它放在一个函数里(可以叫它 main):
def main():
# put your code here
if __name__ == "__main__": # not needed, just in case...
main()
现在修改你的 setup.py
:
setup(
# ...
entry_points = {
"console_scripts": [
# modify script_name with the name you want use from shell
# $ script_name [params]
"script_name = project.main:main",
],
}
)
就这样。安装后,setuptools 会创建一个可以从命令行调用的包装脚本,这个脚本会调用你的主函数。现在 main.py
可以放在你的项目目录里,你不需要再把它移动到 bin/
目录了。注意,setuptools 会自动把这个脚本放在相对于安装前缀的 bin/
目录里。
例如:
python setup.py install --prefix ~/.local
把你的项目包安装在
~/.local/lib/python<version>/site-packages/<package_name>
把你的脚本放在
~/.local/bin/<script_name>
所以确保 ~/.local/bin
在你的 PATH 环境变量中。
更多信息请查看:http://peak.telecommunity.com/DevCenter/setuptools#automatic-script-creation