импорт символов из пакета Python в пространство имен вызывающего - PullRequest
3 голосов
/ 02 июня 2010

У меня есть небольшой внутренний DSL, написанный в одном файле Python, который вырос до такой степени, что я хотел бы разделить содержимое на несколько разных каталогов + файлов.

Новая структура каталогов в настоящее время выглядит следующим образом:

dsl/
    __init__.py
    types/
        __init__.py
        type1.py
        type2.py

и каждый файл типа содержит класс (например, Type1).

Моя проблема в том, что я хотел бы сохранить реализацию кода, использующего этот DSL, максимально простой, что-то вроде:

import dsl
x = Type1()
...

Это означает, что все важные символы должны быть доступны непосредственно в пространстве имен пользователя. Я попытался обновить файл __init__.py верхнего уровня, чтобы импортировать соответствующие символы:

from types.type1 import Type1
from types.type2 import Type2
...
print globals()

вывод показывает, что символы импортированы правильно, но они все еще отсутствуют в коде вызывающего (код, который выполняет import dsl). Я думаю, что проблема в том, что символы на самом деле импортируются в пространство имен 'dsl'. Как я могу изменить это так, чтобы классы также были непосредственно доступны в пространстве имен вызывающего абонента?

Ответы [ 4 ]

3 голосов
/ 02 июня 2010

Вы должны будете сказать

from dsl import *
1 голос
/ 02 июня 2010

Это то, что я бы сделал

В dsl / init __. Py добавьте

def import_symbols(namespace):
    namespace['type1'] = dsl.types.type1
    namespace['type2'] = dsl.types.type2

От абонента сделайте

import dsl

dsl.import_symbols(globals())

Вы можете не только импортировать символы из пакета второго уровня в ваше текущее пространство имен. Определив ваше собственное import_symbols(), вы также имеете более явный контроль над тем, какой символ импортировать, чем импортировать все с помощью import *.

0 голосов
/ 03 июня 2010

@ Eli, @Daniel спасибо за ответ "ага". Я был почти там, но нуждался в дополнительном толчке ...

В основном решение было разделено на два этапа: использовать инициализатор пакета, чтобы «экспортировать» символы второго уровня в пакет верхнего уровня dsl (этот бит у меня уже был), а затем получить эти символы в коде вызывающего абонента с from dsl import *. Это имеет смысл, поскольку вызывающий объект должен действительно контролировать то, что он вводит в свое пространство имен.

from pkg import * кажется, как правило, нахмурился, но в этом случае я думаю, что это разумное решение, так как количество символов, экспортируемых моим пакетом, будет ограничено.

0 голосов
/ 02 июня 2010

Вы не можете этого сделать. Это зависит от пользователя, что они импортируют в свой собственный код. Если они хотят импортировать все в свое пространство имен, они могут сделать from dsl import *, но вы не можете диктовать это.

...