Python根目录脚本调用子包名称及导入报错问题咨询
错误原因
当你导入一个Python包时(比如此处的Rosa.filehandle),如果包的__init__.py为空,Python默认不会自动加载包下的子模块。此时Rosa.filehandle的命名空间里没有fmain这个属性,所以直接访问R.fmain就会抛出属性不存在的报错。
而你之前可以正常运行的import Rosa.filehandle.fmain as f写法,会让Python递归加载路径上的所有父包、子包和目标子模块,同时自动将fmain作为属性挂载到Rosa.filehandle的命名空间中,所以可以正常访问。
解决方法
分为两种方案,你可以根据需求选择:
方案1:修改子包的__init__.py(推荐,适合包对外暴露统一接口的场景)
在Rosa/filehandle/__init__.py中添加如下代码:
from . import fmain
这样只要Rosa.filehandle被导入,就会自动加载fmain子模块并挂载到包属性下,你原本的写法就可以正常运行:
import Rosa.filehandle as R a = R.fmain.string_fasta
如果需要更简化的调用,还可以直接把函数导出到包层面:
# 写在Rosa/filehandle/__init__.py里 from .fmain import string_fasta
调用时可以直接写:
import Rosa.filehandle as R a = R.string_fasta
方案2:不修改__init__.py,调整导入写法
你可以手动导入需要的子模块,或者直接导入目标对象:
- 直接导入子模块:
from Rosa.filehandle import fmain a = fmain.string_fasta
- 直接导入目标函数:
from Rosa.filehandle.fmain import string_fasta a = string_fasta
- 手动加载子模块后通过父包访问:
import Rosa.filehandle as R import Rosa.filehandle.fmain # 手动加载子模块,自动挂载到R的属性下 a = R.fmain.string_fasta
不同层级模块调用规则
不管是调用层级更浅还是更深的模块,都遵循以下规则:
- 顶层脚本(比如你放在根目录的
current_code.py)优先使用绝对导入:从项目根包开始写完整路径,格式为from 根包.子包.模块 import 目标对象/子模块,不会出现路径歧义。 - 包内部的模块可以用相对导入:用点号表示层级,
.代表当前目录,..代表上级目录,比如你在fmain.py中要导入punnet包下的pmain.py,可以写from ..punnet import pmain,相对导入不能用在顶层执行的脚本中。
内容的提问来源于stack exchange,提问作者Aditya Prakash
相关产品推荐
相关产品推荐

