模块的四种形式
什么是模块
模块就是一些列功能的集合体,就是一堆函数放在一个.py
文件中,模块的名字是根据文件名字取的,和文件的名字是一样的
模块的四种形式
自定义模块
和字面意思一样,就是自己定义的模块,也就是自己写的一个py文件,在文件里面写很多的函数
第三方模块
已被编译为共享库或者DLL的c或c++扩展
内置模块
使用c编写并链接到python解释器的内置模块
包
把一些列模块组织到一起,就给“包”起来
使用模块的好处
可以提升开发效率
然后就是分工明确,可以很清楚的去写代码,以及理解代码
模块的调用
import
from...import
相同点:
- 两者都会执行模块对应的文件,两者都会产生模块的名称空间
- 两者调用功能时,需要跑到定义时寻找作用域关系,与调用位置无关
不同点
- import需要加前缀;from...import...不需要加前缀
循环导入问题
就是在调用的时候会出现另一个py文件中也会执行调用我们在用的文件,就会出现报错的情况。
然后就是我在学习这个过程中以为导包一直执行
其实导包只会执行一次
所以不会像我想的一样一直会循环导着没完
还有就是解决循环导入问题的方法就是避免循环导入
模块的搜索路径
导入模块时查找模块的顺序是:
- 先从内存中已经导入的模块中寻找
- 内置的模块
- 环境变量sys.path中找
py文件的两种用途
python文件总共有两种用途,一种是执行文件;另一种是被当作模块导入。
编写好的的一个python文件可以有两种用途:
1.脚本,一个文件就是整个程序,用来被执行(也就是在文件里面有执行包内函数的语句,直接import
调用文件就可以直接执行 文件中的执行语句,在调用文件的地方打印)
2.模块,文件中存放着一堆功能,用来被导入使用(也就是在文件中存放着很多个写好的函数,但是 没有执行语句,可以使用 from 文件名 import 某个函数名
调用模块中的需要使用的一个功能)
还有就是一个将调用的运行变为自己小秘密的时候的操作
如果直接运行run.py会直接运行aaa.py中的f1()
和f2()
,但是如果我们在aaa.py中加上if __name__ == '__main__':
这句话,则可以防止运行run.py时执行f1()
和f2()
。因为当aaa.py被直接执行,即当做执行文件的时候__name__ == '__main__'
; 在aaa.py被当做模块直接运行的时候__name__ == 'aaa'
。由此可以让aaa.py在不同的场景下有着不同的用法。
# aaa.py
x = 1
def f1():
print('from f1')
def f2():
print('from f2')
if __name__ == '__main__':
f1()
f2()
直观理解:
对于当前运行的程序test.py而言,name 变量的值是"main"。
如果run.py调用了test.py,即import test,那么对test.py而言__name__变量的值是"test",对于run.py而言__name__变量的值是"main"。
背后原因:
有时我们写了可以直接被执行的模块(.py文件),但是在另一个程序中调用它时,我们其实只是想用一用里面写好的函数,而不是全都执行一遍。那么我们就可以把执行的部分放到if name == 'main' 中进行判断。
如果if name == 'main' 为真,就说明我们是在直接执行这个模块,那么所有的操作都要运行一遍;但如果为假,就说明我们是引用了这个模块,只有在需要用到它的函数时,才会被调用执行。
编译python文件
(了解)
https://www.cnblogs.com/nickchen121/p/10802465.html
包
什么是包
包是模块的一种形式,包的本质就是一个含有.py的文件的文件夹
我的理解
其实包就是给我们所编写的模块的一个整合,里面是可以包括py文件以及其他的包,还有就是在包里面有一个__init__.py
文件,就相当于给包下面的文件一个目录的形式让包外面的文件可以直接调用包名,达到调用包里面的模块的作用,还有就是我发现如果init文件中有一个没有导入进来,包外文件在调用的时候如果采用 from 包名 import 模块名的方法调用的话,会执行以一遍init中的调用,如果说init导入的模块中含有类似于print的打印的东西,就会导致终端上不仅会打印你调用文件的内容,还会打印init所调用的内容,还有就是再init中写下调用包内模块的语句,调用会更加方便。(个人理解,还没有去系统学习,只是自己看了之后,总结一下的)