首页 > 解决方案 > 在 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()显示所有类名都导入到包命名空间中。

但是,当我运行时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'

我应该如何将 60 多个类从 Main.py 提取到其他模块而不重写这些类的所有调用?

标签: python

解决方案


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

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

请注意,您可以定义您的类__all__以限制在from ... import *. 这样您就不会在主脚本的命名空间中泄漏其他名称。


推荐阅读