文章记录了构成包的条件,导包中出现的一些错误,最后总结自定义包管理的“思维导图”。
阅读时间5分钟。
构成包的两个条件
- 文件夹下面包含__init__.py文件
- 文件夹不作为顶层模块,即文件夹下直接子代码文件不能作为程序入口
两种导包方法
- 直接用包名进行导入,在sys.path中的路径中查找包
- 使用相对导入方法,即使用符号’.‘指明当前包,’..'指明上一层包
常见错误
no module ****
sys.path是一个预定义的列表,python解释器会在sys.path中给定的路径下找包,像系统包等等之所以能够导入就是因为路径在sys.path中。出现这个问题的直接原因就是sys.path列表里面没有对应文件所在的路径,出现的间接原因可能是(直接使用包名导入):
- 两个完全独立的(即不属于同一个顶层包(有嵌套关系的最顶层包))的包相互调用;
- 两个没有嵌套关系,但同属于一个顶层包的包相互调用;
- 同一个包中的导入
解决办法:
- 将绝对路径添加导sys.path列表里面
- 从最顶层包开始导入
- 对于同一包中导入可以直接使用相对导入,即需使用符号’.’
ValueError: attempted relative import beyond top-level package 或者 attempted relative import no package
这个问题是相对路径导入错误,可能的原因是:
- 使用相对路径导入方法,两个完全独立的(即不属于同一个顶层包(有嵌套关系的最顶层包))的包相互调用;
- 对于两个没有嵌套关系,但同属于一个顶层包的包相互调用,在包内因为作为了程序入口,不能作为包,所以导致了第一个可能原因的发生;
自已包管理“思维导图”
这里作为一名研究者来说的话,下面的思路应该够了。
首先在项目根目录下,创建一个main.py作为入口函数,其余的包全放在lib包下面,这样main能够访问lib包,且lib包内的所有嵌套包均能相互访问。
换句话说,你只需要将入口函数独立出来,其余的功能函数或类对象作为接口全放在lib下,保证了接口之间的相互调用。