Как импортировать классы, определенные в __init__.py - PullRequest
88 голосов
/ 24 февраля 2009

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

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

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

EDIT

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

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

Ответы [ 7 ]

67 голосов
/ 24 февраля 2009
  1. 'lib/ должен находиться в 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 в 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
11 голосов
/ 30 июня 2015

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

from . import Helper

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

(подтверждено Python 2.7.10, работает в Windows.)

7 голосов
/ 24 февраля 2009

Вы просто помещаете их в __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'>
4 голосов
/ 24 февраля 2009

Редактировать, так как я неправильно понял вопрос:

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

3 голосов
/ 03 июня 2014

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

from .helperclass import Helper

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

from lib import Helper

1 голос
/ 24 февраля 2009

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

from lib import *
0 голосов
/ 04 января 2011

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

import __init__ as lib
...