2012-10-19 16 views
35

Khi mô tả gói python trong setup.py trong Python, có cách nào để tự động lấy mọi thư mục có một số __init__.py trong đó và bao gồm đó là gói phụ?làm cho các đoạn trong Python tự động tìm các gói

tức là nếu cấu trúc là:

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

Tôi muốn tránh thực hiện:

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

và thay vào đó chỉ làm:

packages = ['mypackage'] 

và có nó tự động tìm những thứ như ab vì chúng có tệp init. cảm ơn.

+0

Chỉ cần chắc chắn rằng bạn không cho phép bất kỳ tin rác tích lũy trong cơ cấu gói của bạn trước khi xây dựng nếu bạn làm điều này. – asmeurer

Trả lời

13

Cách đơn giản nhất (mà tôi biết) là sử dụng pkgutil.walk_packages để mang lại gói:

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 ... 
) 
+1

Có thể (thực sự, có nhiều khả năng * là *) cách tốt hơn để làm điều này ... Tôi chỉ không biết chúng (chưa) :-) –

+7

find_packages() từ setuptools thực hiện chính xác như nhau về cơ bản, xem câu trả lời của tôi – dm76

+1

@ dm76 có nhưng OP là yêu cầu cho distutils, không setuptools. Tui bỏ lỡ điều gì vậy? – Paolo

98

Tôi muốn giới thiệu cách sử dụng find_packages() chức năng có sẵn với setuptools như:

from setuptools import setup, find_packages 

và sau đó làm

packages=find_packages() 
+1

Lưu ý rằng 'find_packages()' không tìm thấy> 3.3-style no-__init__.py gói. Vé về vấn đề này là tại https://bitbucket.org/pypa/setuptools/issue/97. Vì vậy, bây giờ, cần thêm các tệp '__init __. Py' vào các gói cho' find_packages() 'bộ sưu tập tự động, hoặc bạn phải đặt tên chúng một cách rõ ràng trong' gói'. Cập nhật – Iodnas

+1

: Ngay cả danh sách rõ ràng cũng gây ra vấn đề nếu các tệp '__init __. Py' không được sử dụng trên Python 3.3 ('tệp init gói' mymod/mysubmod/__ init__.py 'không tìm thấy (hoặc không phải là tệp thông thường)'). – Iodnas

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() 
... 
) 
15

Tương tự như câu trả lời dm76, chỉ là tôi cũng có các bài kiểm tra trong repo của tôi, vì vậy tôi sử dụng:

from setuptools import find_packages 

packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),