将符号从python包导入调用者';s名称空间

将符号从python包导入调用者';s名称空间,python,import,namespaces,packages,Python,Import,Namespaces,Packages,我在一个Python文件中编写了一个小的内部DSL,这个文件已经发展到我希望将内容拆分为多个不同的目录和文件的地步 当前新的目录结构如下所示: dsl/ __init__.py types/ __init__.py type1.py type2.py 每个类型文件都包含一个类(例如Type1) 我的问题是,我希望使用此DSL的代码实现尽可能简单,例如: import dsl x = Type1() ... 这意味着所有重要的符号

我在一个Python文件中编写了一个小的内部DSL,这个文件已经发展到我希望将内容拆分为多个不同的目录和文件的地步

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

dsl/
    __init__.py
    types/
        __init__.py
        type1.py
        type2.py
每个类型文件都包含一个类(例如
Type1

我的问题是,我希望使用此DSL的代码实现尽可能简单,例如:

import dsl
x = Type1()
...
这意味着所有重要的符号都应该直接在用户的名称空间中可用。我已尝试更新顶级
\uuuu init\uuuu.py
文件以导入相关符号:

from types.type1 import Type1
from types.type2 import Type2
...
print globals()
输出显示符号已正确导入,但它们仍然不存在于调用方的代码中(执行
导入dsl的代码)。我认为问题在于符号实际上被导入到了“dsl”名称空间。我怎样才能改变这一点,使类也可以直接在调用方的命名空间中使用呢

from dsl import *

你不能那样做。这取决于用户将什么导入到自己的代码中。如果他们想将所有内容导入自己的名称空间,他们可以从dsl import*
执行
,但您不能口述这一点。

这就是我要做的

在dsl/init__u;.py中,添加

def import_symbols(namespace):
    namespace['type1'] = dsl.types.type1
    namespace['type2'] = dsl.types.type2
从打电话的人那里,你知道吗

import dsl

dsl.import_symbols(globals())

通过定义您自己的
import_symbols()
,您不仅可以将符号从二级包导入到当前名称空间中,还可以更明确地控制要导入的符号,而不是使用
import*

@Eli导入所有内容,@Daniel感谢“aha”的回答。我就快到了,但需要额外的推动

基本上,解决方案分为两个阶段:使用包初始化器将“导出的”二级符号拉入顶级
dsl
包(我已经有了这个位),然后使用
从dsl导入*
将这些符号拉入调用者的代码。这是有道理的,因为调用者应该真正控制他们将什么拉入他们的名称空间


从pkg导入*
似乎普遍不受欢迎,但在这种情况下,我认为这是一个合理的解决方案,因为我的软件包导出的符号数量有限。

实际上,符号比dsl低一级。e、 g.dsl.types.type1.@WaiYipTung:Paul C说他已经更新了顶层的
\uuuu init\uuuuu.py
以包含这些符号,所以从dsl导入*
中执行
应该仍然有效,即使这些符号最初是向下定义一级的。您是如何做到“将第二级符号拉入顶层的
dsl
包”的?