在Python中使distutils自动查找包

当在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'] 

并让它自动find像aba东西,因为它们有一个init文件。 谢谢。

最简单的方法(我知道)是使用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 ... ) 

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

 from setuptools import setup, find_packages 

然后呢

 packages=find_packages() 

同dm76的答案,只是我也有我的回购testing,所以我使用:

 from setuptools import find_packages packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]), 
 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() ... ) 

直接replacesetuptools.find_packages()

 from pkgutil import walk_packages from fnmatch import fnmatch as wc_match from itertools import chain def find_packages(where, exclude=None): if not exclude: exclude = () if isinstance(where, str): where = (where, ) ret_list = [] for name in chain.from_iterable(map(lambda w: (n for _, n, ispkg in w if ispkg), (walk_packages(p) for p in where))): if not any(wc_match(name, p) for p in exclude): ret_list.append(name) return tuple(ret_list) find_packages(".", exclude=['*.test*']) find_packages((".", "lib", "src"), exclude=['*.test*']) from distutils.core import setup setup( ..., packages=find_packages(".", exclude=['*.test*']), ..., ) 

你也可以简单地把它转换成懒惰的生成器。