You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python包中跳过中间模块直接导入子模块?

解决Python包导入层级隐藏问题

首先得提个关键注意点:Python的模块名不能是纯数字(比如1.py、3.py),这违反了Python标识符的命名规则,直接使用会触发语法错误。所以先建议你把这类模块改名,比如1.py改成module1.py、3.py改成module3.py,下面的示例都基于改名后的结构讲解。

为什么from .A import *无效?

你之前尝试的from .A import *只会导入A模块中__all__指定的成员(如果没定义__all__,则导入所有非下划线开头的成员),但不会把A目录下的子模块(比如module1.py)本身导入到root的命名空间里。要实现隐藏中间层级的效果,需要显式地把子模块绑定到root的命名空间。

具体解决步骤

假设你的目录结构修改后是这样:

root/
    __init__.py
    A/
        __init__.py
        module1.py  # 原1.py
        module2.py  # 原2.py
    B/
        __init__.py
        module3.py  # 原3.py
  1. 修改root/__init__.py:
    在这个文件里显式导入需要暴露的子模块,直接绑定到root的命名空间:

    # 把A下的module1导入到root模块
    from .A import module1
    # 把B下的module3导入到root模块
    from .B import module3
    
  2. 验证导入效果:
    现在你就可以直接从root导入目标模块了:

    # 导入module1模块
    from root import module1
    # 从module3导入a_func
    from root.module3 import a_func
    

如果坚持要用数字命名模块(不推荐)

如果因为特殊需求必须保留1.py、3.py这类名字,你需要用importlib来动态导入,因为直接用from .A import 1是语法错误。在root/__init__.py中写:

import importlib

# 动态导入A下的1.py模块,并绑定到root的命名空间(用合法的名字比如m1)
m1 = importlib.import_module('.A.1', package='root')
# 如果一定要用数字作为属性名(不建议,不符合PEP8)
globals()['1'] = importlib.import_module('.A.1', package='root')
globals()['3'] = importlib.import_module('.B.3', package='root')

但这种方式会让代码可读性变差,还可能引发潜在问题,所以强烈建议遵循Python的命名规范修改模块名。

关于setuptools配置

你当前的packages=['root', 'root.A', 'root.B']配置是没问题的,不需要修改,它能正确识别所有子包。

内容的提问来源于stack exchange,提问作者darkpirate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:28:02