web-dev-qa-db-fra.com

Comment importer des classes définies dans __init__.py

J'essaie d'organiser certains modules pour mon propre usage. J'ai quelque chose comme ça:

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

Dans lib/__init__.py, Je veux définir certaines classes à utiliser si j'importe lib. Cependant, je n'arrive pas à comprendre sans séparer les classes en fichiers et les importer in__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 ça:

    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-ce possible ou dois-je séparer la classe dans un autre fichier?

MODIFIER

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

L'exemple ici décrit les références intra-paquet. Je cite "les sous-modules doivent souvent se référer les uns aux autres". Dans mon cas, lib.settings.py a besoin de Helper et lib.foo.someobject doit avoir accès à Helper. Où devrais-je définir la classe Helper?

90
scottm
  1. Le répertoire parent de lib/ Doit être dans 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
    

Ensuite, l'exemple suivant devrait fonctionner:

from lib.settings import Values
from lib import Helper

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

__init__.py Définit l'apparence de votre paquet de l'extérieur. Si vous devez utiliser Helper dans settings.py, Définissez Helper dans un autre fichier, par exemple, 'lib/helper.py'.

. 
 | `- import_submodule.py 
` - lib 
 | - __init __. py 
 | - foo 
 | | - __init __. py 
 | `- quelque-objet.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
68
jfs

Si lib/__init__.py définit la classe Helper puis dans settings.py, vous pouvez utiliser:

from . import Helper

Cela fonctionne parce que. est le répertoire courant et agit comme un synonyme du paquet lib du point de vue du module de configuration. Notez qu'il n'est pas nécessaire d'exporter Helper via __all__.

(Confirmé avec python 2.7.10, sous Windows.)

12
yoyo

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'>
7
Aaron Maenpaa

Modifier, car j'ai mal compris la question:

Il suffit de mettre la classe Helper dans __init__.py. Cest parfaitement Pythonic. Cela semble étrange venant de langages comme Java.

4
Richard Levasseur

Ajouter quelque chose comme ceci à lib/__init__.py

from .helperclass import Helper

maintenant vous pouvez l'importer directement:

from lib import Helper

3
Dawid Gosławski

Oui c'est possible. Vous voudrez peut-être aussi définir __all__ dans __init__.py des dossiers. C'est une liste de modules qui seront importés quand vous le ferez

from lib import *
1
vartec