1.模块与包的介绍
1.模块 Module
* 其实就是一个python文件, .py为结尾的文件
之所以会出现这个东西,其实就是我们原先写的函数在其他py文件中,那么是否可以把其他文件的函数直接拿过来进行调用呢?就像C一样有一个链接可以把库函数链接到本地而无需自己去再次实现.那么我们能明确py文件中可以包含变量,函数以及类的定义,这样模块的使用就可以进行偷懒了.
#此处为最简单的导入,即将my_module整个模块导入 import my_module #将一个自己导入的模块重命名,方便自己使用 import my_module as my_mod #指定变量,类,函数导入 form my_module import 变量名,类名,函数名 #导入模块的所有 form my_module import * #若一个模块中有 __all__ ,那么此时form my_module import *就会只提供 __all__ 指定的所有 #模块my_module __all__ = ['funcA'] def funcA() XXX def funcB() XXX #调用my_module form my_module import * #能调用的只有funcA,而没有funcB
需要告诉解释器你所指定的模块到底在哪
1.标准做法是把其放入到环境变量中去.类似于python下载好后自带的模块可随便导入
2.或者在import时告诉解释器模块的绝对路径或者相对路径
2.包 Package
是一种用于组织 Python 模块的层级结构.允许你将相关的模块组织在一起,以便更好地管理和维护代码.包的本质上是一个包含了一个或多个模块的文件夹.
my_package/ # 包的根目录 __init__.py # 包的初始化文件 module1.py # 包中的一个模块 module2.py # 包中的另一个模块 sub_package/ # 子包 __init__.py # 子包的初始化文件 sub_module1.py # 子包中的模块 sub_module2.py # 子包中的另一个模块
1.
__init__.py
:这个文件是包的标识文件。即使它是空的,它也必须存在,告诉Python解释器这是一个包。可以在其中编写初始化代码或设置__all__
来控制包的导出内容。2.
module1.py
和module2.py
:这些是普通的Python模块文件,可以包含函数、类和变量等。3.
sub_package/
:这是一个子包,它本身也有自己的模块和__init__.py
文件,允许你进一步组织代码。
3.其他
1.库:来源于其他编程语言,例如C++便有动静态库能被使用,一旦调用其库就能访问库中的函数进行操作.那对应到python中其实就是既可以是模块又可以是包
2.框架:一种特殊的包,他的实现一定程度上解决了计算机一些比较公式化的项目,调用框架方便程序员对项目进行快速搭建.
2.模块与包的细节介绍
1.分类
1.标准类
下载python时自带的模块和包,有一些无需import便可直接执行,这是因为该类函数调用频繁,开发者就将其直接写入环境变量中去,无需import导入直接使用即可 ; 而其他的标准的模块和包保存在本地的文件中,那么需要进行手动的import导入即可正常使用
2.第三方类
其他开发人员自己制作的模块和包,需要我们自己去下载并且配置到本地才可import导入
3.自定义类
自己写的模块和包,这些东西可以被我们自己调用.亦可传入到网站上供给其他人使用,那么此时我们的自定义类与别人而言其实就是第三方类
3.简单创建模块和包
1.创建模块
由于模块其实就是.py的文件,那其实只需要创建一个.py文件即可.一旦其他的文件想要去执行该模块只需要import即可
2.创建包
创建一个文件夹,该文件夹中添加一个__init__.py文件,此文件就是标志着该文件夹为包的标志.这样我们就得到了一个包,此后需要调用直接import导入即可.
4.包的细节
1.__init__.py作用
首先我们需要介绍一下__init__.py文件是做什么的?
我们当然是知道该文件的出现其实意味着当前的文件夹为一个包.那么既然是个包就可以被import导入,我们在__init__.py文件中编写一段debug输出"start init".随后导入包的文件执行时我们会发现其实当前的文件也输出了"start init"这段信息.
#形如当前文档树 ########################## project/ test.py package/ __init__.py ########################## #__init__.py文件 print("start init") #test.py文件 import package print("test.py finish") #执行test.py <<start init <<test.py finish
我们会发现其实所谓的__init__.py文件其实就是一个自动执行的初始化文件.一旦一些文件包含了这个包,那么就会触发该包的__init__.py文件.
2.导入包并执行
#结果输出为: start package's init hello world start funcA
分析过程:
1.我们调试main文件时,优先去导入包package.
2.package为一个包,故优先执行打印start package's init,随后package包导入funA模块
3.随后打印hello world执行funA函数
注意:
如果main函数import了package的包,而__init__.py的内容为空.那么main就无法调用.因为此时就包含了给package的包,而其他的模块未被导入.(我附庸的附庸不是我的附庸) 那么我们也十分清楚__init__.py文件存在的意义,我们只需要把需要上层需要的模块导入其中,随后import这个包时自动触发__init__.py文件,就顺便把包里的模块包含进来,这样就到达调用包中内容的作用了.特别需要注意的是:__init__.py在导入模块时,需要import的是最外层开始到模块的绝对路径,否则会报错
5.导入模块与包过程
1.form...import...导入的注意事项
1.form A import B,首先需要知道的是A一定是比B大的
2.由于大小关系,我们能推出其实导入形式:大包导入小包,包导入模块,模块导入函数/变量/类
3.导入的语法是:A的结构要写的详细,而B是最终我们想要导入的内容比较简略,调用的时候无需加A来修饰B,直接调用B即可
4.form...import *的形式是将...处导入有两种形式:要么...处存在__all__=["..."]的形式,这样就只能调用__all__中的内容;如果不存在,那么就是将所有的内容都可访问
2.导入过程解释
1.第一次导入
1.首先会对import的文件的命名空间中执行其所有的代码.假设我有一个test.py导入了funcA.py的模块,funA有一段打印"hello funA",那么执行test.py时优先在funcA.py命名空间下执行其所有的函数,也就是"hello funA".
2.那么随后就会创建一个模块对象(class),并将模块内的所有顶级变量以属性的形式绑定到模块对象当中去.该对象就拥有了模块特有的变量/函数/类
3.在import位置处引入之前生成的模块对象,此时的生命周期与当前import的位置息息相关
2.第二次及以上导入
执行第一次导入的第3步.即引入模块对象,生命周期与import位置一致
3.结论
1.多次导入模块不会反复执行,因为多次导入只是拿取引用
2.import导入与form...import...导入的其实都会执行命名空间内的所有代码,那么就不会存在所谓"哪个更节省空间",即form...import...只能使用某个函数只代表当前可访问的内容是该特定函数,而不是只取了这个模块的特定函数
3.如何寻找导入的模块
1.内置模块
2.sys.path
当前目录->环境变量PYTHINPATH中指定路径->python安装路径的.pth->lib库->lib库的.pth