运行 仅当 __name__ == “__main__” 时才从 setuptools 设置函数?
Run setup function from setuptools only if __name__ == "__main__"?
我想在 setup.py 中 运行 setup() 仅当模块实际上是 运行 时。所以我想做类似的事情:
from setuptools import setup
def somefunction():
...
if __name__ == "__main__":
setup(...)
(我想在文档构建过程中使用的另一个 python 脚本中使用文件中的一些已定义函数,这些函数在 setup() 调用中使用)
这可能吗?不允许?灰心?为什么?
我找不到任何关于此的文档,但奇怪的是所有示例都没有使用“main”的测试,所以我想知道是否有任何问题导致使用此问题.
应该没有问题。我建议始终使用 if __name__ == "__main__":
条件,即使从未导入该模块。另一方面,我不建议在设置脚本和项目本身的代码之间共享代码。
setup()
调用周围的守卫在实践中并不常见,因为这个文件通常不会 导入 。众所周知是一个安装程序脚本,旨在直接执行。
但是,您可以出于上述原因(“我想使用文件中定义的一些函数”)以及 distutils/setuptools 中的所有内容添加守卫应该仍然可以正常工作。 setup.py
脚本在其中定义库函数有点不寻常,因此您可能会问自己是否有更好的归宿来放置这些函数,而不是直接在安装程序脚本本身中编写它们。
Is this possible?
是的。
Disallowed?
没有
Discouraged?
有点基于意见。就个人而言,我会说是:不鼓励这样做。
Why?
setup.py
的工作是从 source distribution, period. It is not typically the home for other random tasks such as documentation of build process. This file will not even be included in a wheel distribution 安装您的代码,这可能是目前部署 Python 代码的更典型方式。
作为最后的说明:如果并且当您转向使用 pyproject.toml
的现代 Python 打包实践时,使用 声明式 构建系统,将会是没有setup.py
脚本。那么你将不得不为这些辅助函数找到一个新家。
您可以走不同的路线,将您感兴趣的所有功能添加到一个单独的模块中,该模块通常可由您的程序的其余部分导入。我不建议将包函数放入 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
我想在 setup.py 中 运行 setup() 仅当模块实际上是 运行 时。所以我想做类似的事情:
from setuptools import setup
def somefunction():
...
if __name__ == "__main__":
setup(...)
(我想在文档构建过程中使用的另一个 python 脚本中使用文件中的一些已定义函数,这些函数在 setup() 调用中使用)
这可能吗?不允许?灰心?为什么?
我找不到任何关于此的文档,但奇怪的是所有示例都没有使用“main”的测试,所以我想知道是否有任何问题导致使用此问题.
应该没有问题。我建议始终使用 if __name__ == "__main__":
条件,即使从未导入该模块。另一方面,我不建议在设置脚本和项目本身的代码之间共享代码。
setup()
调用周围的守卫在实践中并不常见,因为这个文件通常不会 导入 。众所周知是一个安装程序脚本,旨在直接执行。
但是,您可以出于上述原因(“我想使用文件中定义的一些函数”)以及 distutils/setuptools 中的所有内容添加守卫应该仍然可以正常工作。 setup.py
脚本在其中定义库函数有点不寻常,因此您可能会问自己是否有更好的归宿来放置这些函数,而不是直接在安装程序脚本本身中编写它们。
Is this possible?
是的。
Disallowed?
没有
Discouraged?
有点基于意见。就个人而言,我会说是:不鼓励这样做。
Why?
setup.py
的工作是从 source distribution, period. It is not typically the home for other random tasks such as documentation of build process. This file will not even be included in a wheel distribution 安装您的代码,这可能是目前部署 Python 代码的更典型方式。
作为最后的说明:如果并且当您转向使用 pyproject.toml
的现代 Python 打包实践时,使用 声明式 构建系统,将会是没有setup.py
脚本。那么你将不得不为这些辅助函数找到一个新家。
您可以走不同的路线,将您感兴趣的所有功能添加到一个单独的模块中,该模块通常可由您的程序的其余部分导入。我不建议将包函数放入 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