2012-10-19 11 views
35

Quando si descrive un pacchetto python in setup.py in distutils in Python, c'è un modo per farlo in modo da ottenere automaticamente ogni directory che ha un __init__.py in esso e includono che come sottopackage?fanno distutils in Python trovano automaticamente i pacchetti

cioè se la struttura è:

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

voglio evitare di fare:

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

e invece basta fare:

packages = ['mypackage'] 

e farlo trovare automaticamente le cose come a e b poiché hanno un file di inizializzazione. Grazie.

+0

Basta fare in modo che non si lascia alcun spazzatura si accumulano nella vostra struttura del pacchetto prima di costruire, se si esegue questa operazione. – asmeurer

risposta

13

Il modo più semplice (che io sappia) è quello di utilizzare pkgutil.walk_packages per dare i pacchetti:

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

Ci possono (anzi, molto probabilmente * sono *) modi migliori per farlo ... Non li conosco (ancora) :-) –

+7

find_packages() da setuptools fa esattamente lo stesso essenzialmente, vedere la mia risposta – dm76

+1

@ dm76 si ma l'OP sta chiedendo distutils, non setuptools. Mi sto perdendo qualcosa? – Paolo

98

mi consiglia di utilizzare i find_packages() funzione disponibile setuptools quali:

from setuptools import setup, find_packages 

e poi fare

packages=find_packages() 
+1

Nota che 'find_packages()' non trova> 3.3-style no-__init__.py packages. Il ticket relativo a questo problema è disponibile all'indirizzo https://bitbucket.org/pypa/setuptools/issue/97. Quindi per ora, è necessario aggiungere i file '__init __. Py' nei pacchetti per la raccolta automatica' find_packages() ', o devi chiamarli esplicitamente in' packages'. Aggiornamento – Iodnas

+1

: anche l'elenco esplicito causa problemi se i file '__init __. Py' non sono usati su Python 3.3 (' pacchetto file iniziale 'mymod/mysubmod/__ init__.py' non trovato (o non un file normale) '). – 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

Stessa risposta dm76, solo che ho anche le prove della mia pronti contro termine, per cui uso:

from setuptools import find_packages 

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