将符号从python包导入调用者的命名空间

时间:2010-06-02 15:24:38

标签: python import namespaces packages

我在一个Python文件中编写了一个内部DSL,它已经发展到我希望将内容分成多个不同目录+文件的地步。

新目录结构目前如下所示:

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 个答案:

答案 0 :(得分:3)

你必须说

from dsl import *

答案 1 :(得分:1)

这就是我要做的事情

在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 *导入每一个符号。

答案 2 :(得分:0)

你做不到。这取决于用户将其导入到自己的代码中的内容。如果他们想要将所有内容导入其命名空间,他们可以执行from dsl import *,但您不能指示这一点。

答案 3 :(得分:0)

@Eli,@丹尼尔感谢“啊哈”的回答。我几乎在那里,但需要额外的轻推......

基本上,解决方案分为两个阶段:使用包初始化程序将“导出的”二级符号拉入顶级dsl包(我已经拥有这个位),然后拉< em>那些符号到from dsl import *的调用者代码中。这是有道理的,因为调用者应该真正控制他们进入命名空间的内容。

from pkg import *似乎总是不赞成,但在这种情况下,我认为这是一个合理的解决方案,因为我的包裹导出的符号数量将受到限制。