在python中导入模块时控制名称空间

时间:2019-02-06 15:50:23

标签: python

我已将我写的项目从1个文件拆分为多个文件 事实是,我创建了大约50个类,并从主文件中调用了这些类,我不想重写所有这些类引用,并在每个类之前添加模块名称。

我试图通过1个程序包(令牌)访问所有这些类

所以我有

Main.py
Tokens / 
   __init__.py
   Gen.py
   BuilltIns.py

想法是用所有类填充程序包名称空间,然后将程序包导入Main.py

__init__.py:
from Gen import *
from BuilltIns import *

Main.py:
from Tokens import *

当我运行__init__时,它运行良好,并且dir()显示所有类名均已导入到包namepace中。

但是,当我运行Main.py时,出现错误消息:

Traceback (most recent call last):
  File "../Main.py", line 1, in <module>
    from Tokens import *
  File "..\Tokens\__init__.py", line 1, in <module>
    from Gen import *
ModuleNotFoundError: No module named 'Gen'

如何在不重写对这些类的所有调用的情况下,将Main.py的60多个类提取到其他模块?

1 个答案:

答案 0 :(得分:1)

您应该使用from Tokens.Gen import ...,因为TokensGen模块所在的软件包。导入路径应相对于主脚本,除非您已修改sys.path以指定在导入期间要搜索的其他目录。

或者,您可以在Tokens/__init__.py中进行from .Gen import *(请注意.之前的Gen)。这表示relative import。运行主脚本时会发生的情况是,在导入期间将当前工作目录添加到要搜索的路径,因此当遇到from Gen import ...时,仅搜索默认位置(不包括{{1 }} 目录)。通过使用相对导入,您可以告诉Python在哪里可以找到相对于当前模块 relative 的模块。

请注意,您可以在__all__中定义您的类,以约束在Tokens期间要导入的内容。这样,您就不会在主脚本的命名空间中泄漏其他名称。