Проблемы импорта с пакетами пространства имен Python

Я пытаюсь использовать концепцию пакетов пространства имен Python для разделения моей библиотеки по нескольким каталогам. В целом, это работает, но у меня есть проблема с импортом имен на уровень пакета проектов.

Моя структура проекта следующая:

Пример структуры проекта

project1/coollibrary/__init__.py

from __future__ import absolute_import

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

from .foomodule import foo

project1/coollibrary/foomodule.py

def foo():
    print ('foo')

project2/coollibrary/__init__.py

from __future__ import absolute_import

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

from .barmodule import bar

project2/coollibrary/barmodule.py

def bar():
    print ('bar')

Оба проекта находятся в ПУТИ:

$ echo ${PYTHONPATH}
/home/timo/Desktop/example/project1:/home/timo/Desktop/example/project2

И я запускаю код отсюда:

$ pwd
/home/timo/Desktop/example
$ python3
>>> import coollibrary
>>> coollibrary.foo() # works
foo
>>> coollibrary.bar() # does not work (the problem)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'bar'
>>> import coollibrary.barmodule 
>>> coollibrary.barmodule.bar() # works
bar

Как исправить код, чтобы я мог импортировать оба foo а также bar прямо из coollibrary пакет. Кроме того, есть ли решение, которое работает как для Python2.7, так и для Python3.4 (другие версии не требуются).

1 ответ

Начиная с Python 3.3, вы можете использовать PEP 420 - неявные пакеты пространства имен.

По сути, вы бы удалили __init__.py файл в обоих репозиториях, и добавьте:

setup(
    ...
    packages=['coollibrary.{foomodule/barmodule}'],
    namespace_packages=['coollibrary'],
    ...
)

на ваш setup.py,

Не могу помочь вам с Python 2.7, хотя...

Другие вопросы по тегам