使 Python 中的 distutils 自动查找包
Posted
技术标签:
【中文标题】使 Python 中的 distutils 自动查找包【英文标题】:make distutils in Python automatically find packages 【发布时间】:2012-10-09 14:15:09 【问题描述】:当在 Python 中的 distutils
中的 setup.py
中描述 python 包时,有没有办法让它自动获取每个包含 __init__.py
的目录并将其作为子包包含在内?
即如果结构是:
mypackage/__init__.py
mypackage/a/__init__.py
mypackage/b/__init__.py
我想避免这样做:
packages = ['mypackage', 'mypackage.a', 'mypackage.b']
而只是这样做:
packages = ['mypackage']
并让它自动找到像 a
和 b
这样的东西,因为它们有一个 init 文件。谢谢。
【问题讨论】:
如果这样做,请确保在构建之前不要让任何垃圾堆积在包结构中。 【参考方案1】:最简单的方法(据我所知)是使用pkgutil.walk_packages
来生成包:
from distutils.core import setup
from pkgutil import walk_packages
import mypackage
def find_packages(path=__path__, prefix=""):
yield prefix
prefix = prefix + "."
for _, name, ispkg in walk_packages(path, prefix):
if ispkg:
yield name
setup(
# ... snip ...
packages = list(find_packages(mypackage.__path__, mypackage.__name__)),
# ... snip ...
)
【讨论】:
可能(确实,很可能有)更好的方法来做到这一点......我只是不知道他们(还):-) setuptools 中的find_packages() 本质上完全相同,请参阅我的答案 @dm76 是的,但 OP 要求的是 distutils,而不是 setuptools。我错过了什么吗?__path__
回复我NameError
,我改用'.'
。
投反对票 - 你能解释一下,以便我可以更好地回答吗?【参考方案2】:
我建议使用 setuptools 提供的 find_packages() 函数,例如:
from setuptools import setup, find_packages
然后做
packages=find_packages()
【讨论】:
请注意,find_packages()
找不到 > 3.3 样式的 no-init.py 包。关于这个问题的票是bitbucket.org/pypa/setuptools/issue/97。所以现在,需要在包中添加__init__.py
文件以供find_packages()
自动收集,或者必须在packages
中显式命名。
更新:如果在 Python 3.3 (package init file 'mymod/mysubmod/__init__.py' not found (or not a regular file)
) 上不使用 __init__.py
文件,即使是显式列表也会出现问题。
现在还有find_namespace_packages()
(参见setuptools.readthedocs.io/en/latest/…)可与PEP 420 命名空间包(python.org/dev/peps/pep-0420)一起使用【参考方案3】:
import re, os
def find_packages(path='.'):
ret = []
for root, dirs, files in os.walk(path):
if '__init__.py' in files:
ret.append(re.sub('^[^A-z0-9_]+', '', root.replace('/', '.')))
return ret
setup(
...
packages = find_packages()
...
)
【讨论】:
【参考方案4】:与 dm76 答案相同,只是我的 repo 中也有测试,所以我使用:
from setuptools import find_packages
packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
【讨论】:
以上是关于使 Python 中的 distutils 自动查找包的主要内容,如果未能解决你的问题,请参考以下文章
win7中的python文件pydistutils.cfg文件在哪里?
基于Cython和内置distutils库,实现python源码加密(非混淆模式)
ImportError:无法从“distutils”(/usr/lib/python3.8/distutils/__init__.py)导入名称“sysconfig”
如何使用 distutils 安装 Python 扩展模块?