102 votes

Comment importer des classes définies dans __init__.py

Je suis en train d'organiser des modules pour mon propre usage. J'ai quelque chose comme ceci:

lib/
  __init__.py
  settings.py
  foo/
    __init__.py
    someobject.py
  bar/
    __init__.py
    somethingelse.py

En lib/__init__.py, je veux définir un certain nombre de classes à utiliser que si je l'importation lib. Cependant, je n'arrive pas à le comprendre, sans séparer les classes dans des fichiers, et de les importer en __init__.py.

Plutôt que de dire:

    lib/
      __init__.py
      settings.py
      helperclass.py
      foo/
        __init__.py
        someobject.py
      bar/
        __init__.py
        somethingelse.py

from lib.settings import Values
from lib.helperclass import Helper

Je veux quelque chose comme ceci:

    lib/
      __init__.py  #Helper defined in this file
      settings.py
      foo/
        __init__.py
        someobject.py
      bar/
        __init__.py
        somethingelse.py

from lib.settings import Values
from lib import Helper

Est-il possible, ou dois-je séparer la classe dans un autre fichier?

MODIFIER

OK, si je l'importation lib à partir d'un autre script, je peux accéder à la classe Helper. Comment puis-je accéder à la classe Helper de settings.py?

L'exemple ici décrit Intra-Paquet de Références. Je cite "submodules souvent besoin de consulter les uns les autres". Dans mon cas, l'lib.settings.py besoin de l'aide et de lib.foo.someobject besoin de l'accès à l'Aide, mais où dois-je définir la classe Helper?

78voto

J.F. Sebastian Points 102961
  1. 'lib/s'répertoire parent doit être en sys.path.

  2. Votre 'lib/__init__.py' pourrait ressembler à ceci:

    from . import settings # or just 'import settings' on old Python versions
    class Helper(object):
          pass
    

Puis l'exemple suivant devrait fonctionner:

from lib.settings import Values
from lib import Helper

Réponse à la version éditée de la question:

__init__.py définit la façon dont votre colis regarde de l'extérieur. Si vous devez utiliser Helper en settings.py puis de définir Helper dans un fichier différent par exemple, 'lib/helper.py'.

.
| `-- import_submodule.py
 `-- lib
 |-- __init__.py
 |-- foo
 | |-- __init__.py
 | `-- someobject.py
 |-- helper.py
 `-- settings.py

2 répertoires, 6 fichiers

La commande:

$ python import_submodule.py

Sortie:

settings
helper
Helper in lib.settings
someobject
Helper in lib.foo.someobject

# ./import_submodule.py
import fnmatch, os
from lib.settings import Values
from lib import Helper

print
for root, dirs, files in os.walk('.'):
    for f in fnmatch.filter(files, '*.py'):
        print "# %s/%s" % (os.path.basename(root), f)
        print open(os.path.join(root, f)).read()
        print


# lib/helper.py
print 'helper'
class Helper(object):
    def __init__(self, module_name):
        print "Helper in", module_name


# lib/settings.py
print "settings"
import helper

class Values(object):
    pass

helper.Helper(__name__)


# lib/__init__.py
#from __future__ import absolute_import
import settings, foo.someobject, helper

Helper = helper.Helper


# foo/someobject.py
print "someobject"
from .. import helper

helper.Helper(__name__)


# foo/__init__.py
import someobject

7voto

Aaron Maenpaa Points 39173

Vous venez de les mettre dans __init__.py.

Donc, avec test / classes.py étant:

 class A(object): pass
class B(object): pass
 

... et test / __ init__.py étant:

 from classes import *

class Helper(object): pass
 

Vous pouvez importer le test et avoir accès à A, B et Helper

 >>> import test
>>> test.A
<class 'test.classes.A'>
>>> test.B
<class 'test.classes.B'>
>>> test.Helper
<class 'test.Helper'>
 

4voto

Richard Levasseur Points 5428

Modifier, car j'ai mal compris la question:

Il suffit de mettre le Helper classe en __init__.py . C'est parfaitement pythonique. Cela semble étrange venant de langages comme Java.

1voto

vartec Points 53382

Oui c'est possible. Vous pouvez également vouloir définir les fichiers __all__ dans __init__.py . C'est une liste de modules qui seront importés quand vous le ferez

 from lib import *
 

0voto

Troy J. Farrell Points 827

Richard a raison. Le balisage Stack Overflow a foiré sa réponse. Il voulait dire importer la classe en lib/__init__.py . (Je ne peux pas éditer sa réponse ou je le ferais ...)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X