Как импортировать классы, определенные в __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 из другого скрипта, я могу получить доступ к классу Helper. Как я могу получить доступ к классу Helper из settings.py?

Пример здесь описывает внутрипакетные ссылки. Цитирую «субмодули часто должны ссылаться друг на друга». В моем случае lib.settings.py нужен Helper, а lib.foo.someobject нужен доступ к Helper, так где же мне определить класс Helper?

Ответов (7)

Решение
  1. ' lib/«S родительский каталог должен быть sys.path.

  2. Ваш ' 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 in, settings.py укажите Helper в другом файле, например, ' lib/helper.py'.

.
| `- import_submodule.py
    `- lib
    | - __init__.py
    | - фу
    | | - __init__.py
    | `- someobject.py
    | - helper.py
    `- settings.py

2 каталога, 6 файлов

Команда:

$ 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

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

Просто введите Helper класс __init__.py . Совершенно питонический. Это просто странно исходить от таких языков, как Java.

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

from lib import *

Может, это сработает:

import __init__ as lib

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

from . import Helper

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

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

Добавьте что-то подобное в lib/__init__.py

from .helperclass import Helper

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

from lib import Helper

Вы просто помещаете их в __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 и Helper

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