48

setup.py当在Python中描述一个 Python 包时distutils,有没有办法让它自动获取其中包含的每个目录__init__.py并将其作为子包包含在内?

即如果结构是:

mypackage/__init__.py
mypackage/a/__init__.py
mypackage/b/__init__.py

我想避免这样做:

packages = ['mypackage', 'mypackage.a', 'mypackage.b']

而只是这样做:

packages = ['mypackage']

并让它自动找到类似的东西ab因为它们有一个 init 文件。谢谢。

4

4 回答 4

113

我建议使用 setuptools 提供的 find_packages() 函数,例如

from setuptools import setup, find_packages

然后做

packages=find_packages()
于 2013-01-17T10:22:49.200 回答
22

最简单的方法(据我所知)是用来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 ...
)
于 2012-10-19T02:00:31.853 回答
20

与 dm76 答案相同,只是我的仓库中也有测试,所以我使用:

from setuptools import find_packages

packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
于 2015-05-10T18:08:36.333 回答
2
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()
...
)
于 2013-05-10T23:51:52.950 回答