2010-06-18 22 views
3

Voici quelques différents paquets Python mon entreprise « foo.com » utilise:Diviser la source Python en répertoires séparés?

com.foo.bar.web 
com.foo.bar.lib 
com.foo.zig.web 
com.foo.zig.lib 
com.foo.zig.lib.lib1 
com.foo.zig.lib.lib2 

Voici la manière traditionnelle de stocker la source sur le disque:

pysrc/ 
    com/ 
    foo/ 
     bar/ 
     web/ 
     lib/ 
     zig/ 
     web/ 
     lib/ 
      lib1/ 
      lib2/ 

PYTHONPATH=pysrc 

Mais pour des raisons d'organisation (équipes différentes, différents contrôle de révision, etc.), nous voulons stocker ces derniers comme suit:

bar/ 
    pysrc/ 
    com/ 
     foo/ 
     bar/ 
      web/ 
      lib/ 
zig/ 
    pysrc/ 
    com/ 
     foo/ 
     zig/ 
      web/ 
      lib/ 
      lib1/ 
      lib2/ 

PYTHONPATH=bar/pysrc:zig/pysrc 

La question est:

Y a-t-il des problèmes avec cette deuxième méthode d'organisation? Par exemple, si nous import com.foo, où Python chercherait-il le __init__.py?

Est-ce que le symblage de ces répertoires aurait du sens? par exemple:

pysrc/ 
    com/ 
    foo/ 
     bar/ -> symlink to /bar/pysrc/com/foo/ 
     zig/ -> symlink to /zig/pysrc/com/foo/ 

Toute suggestion d'organisation de code générale est la bienvenue.

+1

double possible de [modules Python accès du paquet qui est distribué sur différents répertoires] (http://stackoverflow.com/questions/2847146/python-accessing-modules-from-package-that-is-distributed-over-different-director) –

+0

@Ignacio: Merci, je n'ai pas vois celui-là. J'ai ajouté ici la question à propos de symlinking, qui n'a pas été discutée dans l'autre, et qui semble être une solution viable. – dkamins

+0

Cela fonctionne en Python 3.3+, voir http://stackoverflow.com/a/17202582/851737 – schlamar

Répondre

4

Python passera par sys.path dans l'ordre (qui inclut PYTHONPATH et ensuite certains), à la recherche d'un paquet com.foo dans chacun. Le premier qu'il trouve, il utilisera à l'exclusion des autres, contrairement à Perl ou Java qui fusionne efficacement les espaces de noms de paquets ensemble. Il y a des choses que vous pouvez faire pour __path__ qui changent ce comportement, mais "first match wins" est la façon dont Python se comporte immédiatement.

Tant que vous conservez entièrement com.foo.bar entièrement dans la barre/et toute la com.foo.zig entièrement dans zig /, vous ne devriez pas avoir de problèmes avec la deuxième disposition.

1

lecture à travers le PEP 420 page, il semble que vous pouvez ajouter le __init__.py aux paquets partagés suivants:

from pkgutil import extend_path 
__path__ = extend_path(__path__, __name__) 

donc la structure de votre répertoire serait la suivante (marquée d'__init__.py fichiers ont le code ci-dessus):

myroot/ 
├── bar 
│   └── pysrc 
│    └── com 
│     ├── ****__init__.py**** 
│     └── foo 
│      ├── ****__init__.py**** 
│      └── bar 
│       ├── __init__.py 
│       ├── lib 
│       │   ├── __init__.py 
│       │   └── barlib.py 
│       └── web 
│        ├── __init__.py 
│        ├── barweb.py 
└── zig 
    └── pysrc 
     └── com 
      ├── ****__init__.py**** 
      └── foo 
       ├── ****__init__.py**** 
       └── zig 
        ├── __init__.py 
        ├── lib 
        │   ├── __init__.py 
        │   ├── lib1 
        │   │   ├── __init__.py 
        │   │   └── ziblib1.py 
        │   └── lib2 
        │    ├── __init__.py 
        │    └── ziblib2.py 
        └── web 
         ├── __init__.py 
         ├── zigweb.py 

Définir le chemin de python pour pointer vers votre com/ répertoires:

barPath=/myroot/bar/pysrc/ 
zigPath=/myroot/zig/pysrc/ 
export PYTHONPATH=$PYTHONPATH:$barPath:$zigPath 

Pour tester (j'ai essayé sur 2.7.14 et 3.6.4):

from com.foo.bar.web.barweb import BarWeb 
from com.foo.zig.web.zigweb import ZigWeb 
b = BarWeb() 
z = ZigWeb() 

Ne pas avoir les rendements de code __init__.py:

ImportError: No module named zig.web.zigweb