Как импортировать классы, определенные в __init__.py

Я пытаюсь организовать некоторые модули для собственного использования. У меня есть что-то вроде этого:

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

В lib/__init__.py, я хочу определить некоторые классы, которые будут использоваться, если я импортирую lib. Однако я не могу понять, не разделяя классы на файлы и импортируя их в __init__.py.

Вместо того, чтобы сказать:

    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

Мне нужно что-то вроде этого:

    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

Возможно ли это, или мне нужно отделить класс от другого файла?

ИЗМЕНИТЬ

ОК, если я импортирую lib из другого script, я могу получить доступ к классу Helper. Как я могу получить доступ к классу Helper из settings.py?

Пример здесь описывает ссылки внутри пакета. Я цитирую: "подмодулям часто нужно ссылаться друг на друга". В моем случае lib.settings.py необходимо, чтобы Helper и lib.foo.someobject нуждались в доступе к Helper, поэтому где я должен определить класс Helper?

Ответ 1

  • 'lib/ родительский каталог должен находиться в sys.path.

  • Ваш 'lib/__init__.py' может выглядеть так:

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

Затем должен работать следующий пример:

from lib.settings import Values
from lib import Helper

Ответ на отредактированную версию вопроса:

__init__.py определяет, как выглядит ваш пакет извне. Если вам нужно использовать Helper в settings.py, тогда определите Helper в другом файле, например, 'lib/helper.py'.

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

2 directories, 6 files

Команда:

$ python import_submodule.py

Вывод:

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

Ответ 2

Вы просто положили их в __init __. py.

Итак, с test/classes.py есть:

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

... и test/__ init__.py есть:

from classes import *

class Helper(object): pass

Вы можете импортировать тест и иметь доступ к A, B и помощнику

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

Ответ 3

Изменить, так как я неправильно понял вопрос:

Просто поместите класс Helper в __init__.py. Это прекрасно pythonic. Это просто странно происходит из таких языков, как Java.

Ответ 4

Если lib/__init__.py определяет класс Помощника, то в settings.py вы можете использовать:

from . import Helper

Это работает, потому что. является текущим каталогом и действует как синоним пакета lib с точки зрения модуля настроек. Обратите внимание, что нет необходимости экспортировать Helper через __all__.

(Подтверждено с помощью python 2.7.10, работает в Windows.)

Ответ 5

Добавьте что-то вроде этого в lib/__init__.py

from .helperclass import Helper

теперь вы можете напрямую импортировать его:

from lib import Helper

Ответ 6

Да, это возможно. Вы также можете определить __all__ в __init__.py файлах. Это список модулей, которые будут импортированы при выполнении

from lib import *

Ответ 7

Возможно, это может сработать:

import __init__ as lib