壹拾陆
模块基础
一、模块的四种形式
1.1 什么是模块
模块是一系列功能的集合体,因为函数是某一功能的集合体,所以模块可以看作是一系列函数的集合体。
一个文件内部有很多的函数,因此一个文件就可以看成是一个模块。
一个python文件的名称为XXX.py,那么模块的名称就是XXX。
1.2 模块的四种形式
- 自定义模块:自己用python写一个有一定功能的文件,就可以称为一个自定义模块。
- 第三方模块:已经有别人写好的一定功能的模块,使用需要自己安装,目前已有13w+的第三方模块了。
- 内置模块:python解释器自带的模块。
- 包:把一系列模块组合到一起的晚间,文件夹内有__inti__文件。
1.3 为什么用模块
python模块库一开放性的库,大家都可以上传不同功能的模块,直接使用现成的模块,提高开发效率。
1.4 如何使用模块
一般是使用import和from...import...导入模块。
二、import和from...import
2.1 import
import首次导入会先以模块为准创造一个模块的名称空间,在执行模块对应的文件,将执行过程中产生的名字都放入模块的名称空间,最后在当前执行文件中拿到一个模块名。
模块重复导入时,会直接使用之前创造好的结果,不会再重复执行文件,导入多个模块的话,使用逗号分隔开。
2.2 from...import
from...import首次导入会先以模块为准创造一个模块的名称空间,在执行模块对应的文件,将执行过程中产生的名字都放入模块的名称空间,在当前执行文件的名称空间中拿到一个名字,该名字直接指向模块中的某一个名字,意味着可以不用加任何前缀而直接使用。
使用from...import时,不用加前缀,代码简洁,但是容易与当前执行文件中名称空间中的名字产生冲突。
2.3 异同
相同点:1.两者都会执行模块对应的文件,两者都会产生模块的名称空间。2.两者调用功能时,需要跑到定义时寻找作用域关系,与调用位置无关
不同点:import需要加前缀;from...import...不需要加前缀
三、循环导入问题
再使用模块相互导入的时候,容易产生循环导入,致使无法导入,从而报错,例如:
# m1.py
print('from m1.py')
from m2 import x
y = 'm1'
- 创建m2的名称空间
- 执行m2.py,将执行产生的名字丢到m2.py
- 在当前执行文件中拿到m2.x
# m2.py
print('from m2.py')
from m1 import y
x = 'm2'
- 创建m1的名称空间
- 执行m1.py,将执行产生的名字丢到m1.py
- 在当前执行文件中拿到m1.y
# run.py
import m1
-
创建m1的名称空间
-
执行m1.py,将执行产生的名字丢到m1.py
-
在当前执行文件中拿到m1
如果运行run.py,则会报错
ImportError: cannot import name 'y'
如果运行m1.py,则会报错
ImportError: cannot import name 'x'
如果运行m2.py,则会报错
ImportError: cannot import name 'y'
解决方案
我们可以使用函数定义阶段只识别语法的特性解决循环导入的问题,我们也可以从本质上解决循环导入的问题,但是最好的解决方法是不要出现循环导入。
# m1.py
print('from m1.py')
y = 'm1'
from m2 import x
# m2.py
print('from m2.py')
x = 'm2'
from m1 import y
四、模块的搜索路径
4.1 搜索模块路径的方法
模块其实就是一个文件,如果要执行文件,首先就需要找到模块的路径(某个文件夹)。如果模块的文件路径和执行文件不在同一个文件目录下,我们就需要指定模块的路径。
- 先从内存中已经导入的模块中寻找
- 内置的模块中找
- 环境变量中找
4.2 搜索路径以执行文件为准
五、random模块
import random
print(random.random()) #大于0小于1的小数
0.03833739951277726
import random
print(random.randint(1,5))#[1,5]的整数
2
import random
print(random.rangrage(1,5))#(1,5)的整数
3
import random
print(random.uniform(1,3))#(1,3)小数
2.13548941567856
import random
print(random.choice([1,'32',[5,6]])#列表内的任意一个元素
1
import random
print(random.sample([1,'32',[5,6]])
['23', 1]
lis = [1, 3, 5, 7, 9]
# 打乱l的顺序,相当于"洗牌"
random.shuffle(lis)
print(lis)
[9, 1, 5, 7, 3]