Pregunta Cómo importar clases definidas en __init__.py


Estoy tratando de organizar algunos módulos para mi propio uso. Tengo algo como esto:

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

En lib/__init__.py, Quiero definir algunas clases para usar si importo lib. Sin embargo, parece que no puedo resolverlo sin separar las clases en archivos e importarlos en__init__.py.

En lugar de decir:

    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

Quiero algo como esto:

    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

¿Es posible, o tengo que separar la clase en otro archivo?

EDITAR

De acuerdo, si importo lib de otro script, puedo acceder a la clase Helper. ¿Cómo puedo acceder a la clase Helper desde settings.py?

El ejemplo aquí describe las referencias dentro del paquete. Cito "los submódulos a menudo necesitan referirse el uno al otro". En mi caso, lib.settings.py necesita el Helper y lib.foo.someobject necesita acceso a Helper, entonces, ¿dónde debería definir la clase Helper?


76
2018-02-24 17:35


origen


Respuestas:


  1. 'lib/El directorio padre debe estar en sys.path.

  2. Tu 'lib/__init__.py'podría verse así:

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

Entonces el siguiente ejemplo debería funcionar:

from lib.settings import Values
from lib import Helper

Responda a la versión editada de la pregunta:

__init__.py define cómo se ve su paquete desde afuera. Si necesitas usar Helper en settings.py entonces define Helper en un archivo diferente, por ejemplo, 'lib/helper.py'.

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

2 directorios, 6 archivos

El comando:

$ python import_submodule.py

Salida:

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

59
2018-02-24 18:52



Si lib/__init__.py define la clase Helper y luego en settings.py puede usar:

from . import Helper

Esto funciona porque es el directorio actual y actúa como sinónimo del paquete lib desde el punto de vista del módulo de configuración. Tenga en cuenta que no es necesario exportar Helper a través de __all__.

(Confirmado con python 2.7.10, ejecutándose en Windows).


8
2018-06-30 14:27



Simplemente póngalos en __init__.py.

Así que con test / classes.py siendo:

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

... y prueba / __ init__.py siendo:

from classes import *

class Helper(object): pass

Puede importar pruebas y tener acceso a A, B y Helper

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

7
2018-02-24 17:42



Editar, ya que entendí mal la pregunta:

Solo pon el Helper clase en __init__.py. Eso es perfectamente pitónico. Simplemente parece extraño venir de idiomas como Java.


4
2018-02-24 17:42



Agrega algo como esto a lib/__init__.py

from .helperclass import Helper

ahora puedes importarlo directamente:

from lib import Helper


3
2018-06-03 09:39



Sí, es posible. Es posible que también desee definir __all__ en __init__.py archivos. Es una lista de módulos que se importarán cuando lo haga

from lib import *

1
2018-02-24 17:49



Quizás esto podría funcionar:

import __init__ as lib

-5
2018-01-04 15:09