仅当__name__ == "__main__" 时,才从设置工具运行设置功能?



我想在 setup.py 中运行setup((,只有当模块实际运行时。所以我想做这样的事情:

from setuptools import setup
def somefunction():
...
if __name__ == "__main__":
setup(...)

(我想在文档构建过程中使用的另一个 python 脚本中使用文件中一些定义的函数,这些函数在 setup(( 调用中使用(

这可能吗?禁止?气馁?为什么?

我找不到任何关于此的文档,但奇怪的是,所有示例都没有将测试用于">main",所以我想知道是否有任何使使用它存在问题的地方。

在实践中,setup()呼叫周围的警卫并不常见,因为通常不会导入此文件。众所周知,它是一个安装程序脚本,旨在直接执行。

但是,您可以出于上述原因添加保护(">我想使用文件中定义的一些函数"(,并且 distutils/setuptools 中的所有内容仍然应该正常工作。setup.py脚本在其中定义库函数有点不寻常,因此您可能会问自己是否有更好的此类函数,而不是直接在安装程序脚本本身中编写它们。

这可能吗?

是的。

禁止?

不。

气馁?

有点基于意见。就个人而言,我会说是的:不鼓励这样做。

为什么?

setup.py的工作是从源代码分发中安装代码。它通常不是其他随机任务(如构建过程文档(的主页。这个文件甚至不会包含在轮子发行版中,这可能是当今部署 Python 代码的更典型的方式。

最后要注意的是:如果你转向使用pyproject.toml的现代Python打包实践,使用声明式构建系统,将不会有setup.py脚本。然后,无论如何,您都必须为此类辅助功能找到一个新家。

应该不是问题。我建议始终使用if __name__ == "__main__":条件,即使从未导入模块。另一方面,我不建议在安装脚本和项目本身的代码之间共享代码。

你可以走不同的路线,将所有感兴趣的函数添加到一个单独的模块中,该模块通常可由程序的其余部分导入。我不建议将包函数放入setup.py,因为安装文件旨在存在于包之外。您可能需要一个实用程序函数来按setup.py中的路径导入模块。我通常使用看起来像这样的东西:

def import_file(name, location):
"""
Imports the specified python file as a module, without explicitly
registering it to `sys.modules`.
"""
if sys.version_info[0] == 2:
# Python 2.7-
from imp import load_source
mod = load_source(name, location)
elif sys.version_info < (3, 5, 0):
# Python 3.4-
from importlib.machinery import SourceFileLoader
mod = SourceFileLoader(name, location).load_module()
else:
# Python 3.5+
from importlib.util import spec_from_file_location, module_from_spec
spec = spec_from_file_location(name, location)
mod = module_from_spec(spec)
spec.loader.exec_module(mod)
return mod

最新更新