2010-06-02 2 views
3

У меня есть небольшая внутренняя DSL, написанная в одном файле Python, который вырос до такой степени, что я хотел бы разделить содержимое на несколько разных каталогов + файлов.импорт символов из пакета 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. Как это изменить, чтобы классы также были доступны в пространстве имен вызывающего?

ответ

2

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

from dsl import * 
+0

На самом деле символы находятся на одном уровне от dsl. например dsl.types.type1. –

+1

@WaiYipTung: Пол С говорит, что он обновил верхний уровень '__init__.py', чтобы включить эти символы, поэтому выполнение 'from dsl import *' должно работать, даже эти символы изначально определяются на один уровень вниз. –

0

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

1

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

В DSL-/INIT __. Ру, добавьте

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

От абонента, сделать

не
import dsl 

dsl.import_symbols(globals()) 

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

0

@Eli, @ Даниэль благодарит за ответ «ага». Я был почти там, но нуждался в дополнительном подталкивании ...

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

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

+1

И как вы это сделали, «вытягивая символы второго уровня в пакет« dsl' верхнего уровня »? – noio

Смежные вопросы