分发Python应用程序

0 投票
1 回答
1325 浏览
提问于 2025-04-15 17:50

我有一个简单的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 个回答

11

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

撰写回答