模块和包
模块和包
一个py文件就是一个模块,模块多了起来就需要组织起来,用的就是包。
导入模块是为了使用已经实现的功能,就好似零件一样,你来进行组装。
模块是一种拿来主义极大提高开发效率。
import 模块
1:执行源文件的代码
2:产生ns存放执行源文件过程中产生的名字
3:import 模块会在当前ns中产生一个新的ns就是执行模块来映射模块文件。
4:from ... import ...不会创建ns,只在当前ns中保存名字。
模块有的大有的小,为了更好的组织模块就有了包。
导入包
1:执行__init__.py文件
2:产生新的ns来存放执行init.py文件执行过程中产生的名字。
导入包并不会导入包内部的模块!!!切记!!!
想要导入模块需要手动的在__init__.py文件中导入模块。
导入包对开发者不友好的地方是,使用了别人的包,你import 包名之后,里面的模块因为包的开发者已经做好了准确的定位。
你使用的时候例如import a包,而这个包下还有包和其他模块。
此时使用的时候,你直接包名.函数名就可以使用了,没有导入其他的模块再定位到函数。
是因为包的开发者已经在包的__init__.py文件中定位了模块,导入包的时候执行__init__.py把下面所有的模块都导入到了内存。
可以用ns来定位到函数
import 包都是从sys.path里面找,找不到就报错,在__init__.py中直接import 是找不到文件的,因为从sys.path中找不到,这就是为什么__init__.py中一般都是from . 或..开头,是为了定位要执行文件的路径来找才能找到。
而三方包都是安装在环境变量里面,环境变量的路径是在sys.path下的,因此肯定能找到包的根路径。
只要直接import 模块/包基本都是安装在环境变量下,如果在__init__.py一般都是找不到的
import的第一步是从内存中找,没有去内置模块里面找,然后就去硬盘,而硬盘的路径就是sys.path列表下的路径,都没有就报错。因为无论你在多么深的包下import 模块都只从sys.path中找。
因此导入模块的时候最先注意的是执行文件是谁,决定了能不能找到其他模块的问题,因此项目中总是会手动把根目录加入到sys.path中这样就可以在任何情况下都用.或者..找到对应模块。
使用者不关心目录的结构,开发者为了方便管理才建立一个个子包,对于开发者而言越精简越好,爱怎么组织怎么组织。
包的开发者可以把包高度定制到,只有包名,然后就可以调用函数了,中间的子包和模块都被他屏蔽掉了。
在包m2下的__init__.py中
from pk1.m1 import f1
这样就能直接用m2.f1()了,因为保证了f1在m2的名称空间下。from后面的包定位把复杂的结构为你屏蔽掉了。
说白了就是如何把路径放到from后,然后import把名字引入到当前的ns下。这样没有开新的ns都是放到了顶层包的ns下。
这就是为什么在高度定制的包里面,你想找源码找不到。