python的setuptools支持`__name__ == "__main__"`的执行方式吗?
我刚开始学习用setuptools来打包,似乎推荐的方式是安装一个Python脚本时,要指定一个脚本名称,这个名称会调用一个函数,像这样:
setup(
# ...
entry_points = {
"console_scripts": [
"script_name": "project.main:main",
],
}
)
这样做显然不再使用Python模块通常的可执行方式,也就是我上次查的时候(已经有一段时间了)是用 if __name__ == "__main__": do_stuff()
。请问setuptools支持这种方式吗?还是说我应该换成定义一个主函数并在entry_points中指定它呢?
1 个回答
9
这里说的是:"script_name = project.main:do_stuff"
,这是用setuptools来做的。
setuptools会创建一个叫script_name
的脚本,这个脚本会导入并运行project.main:do_stuff
这个函数,而不是直接运行脚本本身。你应该再看看setuptools文档中的这一部分(如果你用的是Distribute,可以看这个链接),这样你能理解为什么是这样的。它创建的脚本里仍然包含if __name__ == "__main__"
这段代码。所以,是的,这仍然是执行的标准方式。
这是用setuptools安装的easy_install的一个副本。
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'distribute==0.6.14','console_scripts','easy_install'
__requires__ = 'distribute==0.6.14'
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
load_entry_point('distribute==0.6.14', 'console_scripts', 'easy_install')()
)
我觉得最好是定义一个入口点和一个类似easy_install的脚本。这个脚本会导入并使用入口点,就像你在例子中展示的if __name__ == "__main__": do_stuff()
。这样做对于调试和早期测试非常好,而且如果你使用distutils,就不需要添加或更改任何东西。你还可以有另一个应用程序来调用do_stuff(),这样就可以在不通过命令行运行的情况下访问你的应用,这正是setuptools所做的,distutils则是复制了这个脚本。