周回顾
目录
文件
1.什么是文件
是计算机给用户的直接操作硬件的接口
2.打开文件的两种方式
open
with open
3.操作文件的三种方式
r 只读不写
w 只写 光标在开头 文件存在先清空在写入
文件不存在
a 追加 光标在末尾 文件存在则在后面追加文件不存在则创建
4.打开文件的两种模式
t 模式 文本模式 以文本模式打开
b 模式 以二进制的模式打开
文件对象的内置方法
read() 读全文 r模式 字符为单位 b模式 以字节为单位
readline 读一行
readlines 把每行的数据方到列表里面
write() 写
writelines 把列表里的数据一次性的写入到文件
seek()光标位置 第一个参数移动几个位 第二个参数模式
"""
0 模式 光标从开头开始 r, b模式都可以
1 模式 光标在当前位置开式 b模式可以
2 模式 光标在末尾开始 b模式可以
"""
tell 返回当前位置的光标
函数
1.什么是函数
函数是在不同位置执行同样的代码
循环在相同的位置执行同样的代码
2.函数定义
def 函数名(参数):
函数体代码
return 返回值
定义函数
def 关键字定义
4.调用函数
函数名加括号
5.函数的返回值几种表现形式
当函数体代码中没有return则默认返回None
如果只有return 后面没有写东西的话也返回None
return后面写什么就返回什么
return后面写多个值就以列表的形式返回
怎样获取返回值
变量名 赋值符号 函数名加括号
函数的几种形式
1.无参函数
就是不用给函数传参数
2.有参函数
需要给函数传参数
3.空函数
函数体为空 函数体是pass 或者...什么事都不干
形参实参
在函数定义阶段在函数括号内写的参数
当函数调用的时候 形参和实参会临时绑定关系调用结束后会结束绑定关系
位置参数
形参就从左往右就写个参数就是位置参数
默认参数
形参写 变量名 赋值符号 数据值
可变长形参
*args 位置形参 *号会把多余的位置实参放到元组里然后赋值给args
**kwargs 关键字形参** 会把对于的关键字实参键值对的形式放到字典里面
位置实参
写参数的规律
短的简单的往前放
长的复杂的往后排
一个形参只能赋值一个实参
就是位置参数一定要写在关键字参数之前
可变长实参
*args位置实参 *号会把参数全部打散然后一次性传给形参
**kwargs关键字实参 **会把字典的键值对写成键=值的形式然后一次性的传给形参
名称空间及作用域
1.什么是名称空间
实际上就是储存变量名的地方。
2.代码演示。name = 'jaosn'
当我们给name赋予一个数据值,其实就是我们把name这个名字放入了一个区域内,记录了name 和数据的地址。
3.三大名称空间
1.内置名称空间 - 储存所有内置函数和方法名的地方,如:print len input等
2.全局名称空间 - 当前py文件中的变量名 如 name = 10
3.局部名称空间 - 函数或类子代码里面的变量名 def outer():
4.名称空间存活周期和作用域
1.内置名称空间 - python解释器打开则创建关闭则自动销毁。作用域所有的python文件
2.全局名称空间 - 当前py文件运行则全局名称空间生效,关闭文件则销毁,作用域当前py文件部可以跨文件使用
3.局部名称空间 - 当前函数体代码被执行,只在当前函数题代码内有效
5.名称空间调用顺序
在全局空间内 优先 全局名称空间 ---> 内置名称空间
在局部空间内 优先 局部名称空间 ---> 全局名称空间 ---> 内置名称空间
名字的查找顺序
先判断自己所在的位置
如果自己在局部名称空间 自找不到会到全局找全局找不到回到内置找 找不到报错
如果自己在全局自己找不到则会去内置找 找不到报错
global 与nonlocal
global(变量名)
使用global后可以在局部空间内更改全局空间变量名
nonlocal(变量名)
使用nonlocal可以更改函数体代码外层局部空间变量
函数名的多种用法
def 函数名():
pass
1.函数名可以当作实参传给函数 函数名(函数名)
2.函数名可以作为返回值被输出。
def 函数名():
name = 1
return 函数名
3.函数名可以放入容器类型中,例如字典 可以作为键的值
func_dict = {
'1': 函数名,
'2': 函数名,
'3': 函数名,
'4': 函数名,
}
func_dict.get('1')() 就可以运行了
闭包函数
1.闭包函数是什么?
定义在函数体内部的函数
内部函数用到了外包函数的变量名
2.代码展示
def outer(): # 外层函数
x = 100
def inner(): # 内层函数
print(x) # 内层函数用到了外层函数的变量
3.闭包函数传参优势
def name1(a,b):
print(a,b) # 调用函数中我们需要每次都给这个函数体传参才可以
def outer(a,b):
def name1():
print(a,b)
return name1
变量名 = outer(a,b) # 第一次使用需要传参
变量名() # 参数不变的时候就不需要再次传参了 ,如需要改变则再次改变赋值即可
变量名 = outer(c,d)
装饰器
闭包
也是一种传参方式 至今我们已经学了两种传参方式了
闭包就是 内层函数引用到外层函数的名字
def outer():
name = "jason"
def inner():
print(name)
return inner()
装饰器就是在不改变原函数的函数体和调用方式的情况下为原函数附加功能
无参装饰器
1,什么是装饰器?
当我们需要对一个函数增加额外功能,并且不能改变原来的函数题代码 以及 原来的调用方式。
2.根据闭包函数理论进化为装饰器
def func():
print('执行函数')
def outer(func):
def inner(*args,**kwargs):
# 函数代码执行前增加的功能
res = func(*args,kwargs) # func = 需要被装饰的函数名
# 函数代码执行后增加的功能
return res
return inner()
func = outer(func)
func()
3. 装饰器语法糖
@outer # 相当于 func = outer(func)
def func():
print('执行函数')
func()
4.多重语法糖 - 一个函数作用域多个装饰器
@outer3
@outer2
@outer1
def func():
print('执行函数')
func()
多重语法糖执行顺序,语法糖从下到上执行 先执行 @outer1,得到返回值再执行@outer2,@outer3 ,最后得到的返回值 再次进行生效
有参装饰器
1.什么是有参装饰器?
就是当我们的装饰器里面的函数体代码 需要接收到新的外界的传参
代码展示:
def outer_plus(a,b):
def outer(func):
def inner(*args,**kwargs):
print(a,b)
res = func(*args,**kwargs)
return res
return inner
return outer
这样我们就可以在最外层传参了
@outer_plus(1,2)
def func():
pass
#这样我们就可以直接在语法糖后传入装饰器内部需要的参数
装饰器修复技术
from functools import wraps
def outer(func):
@wraps(func)
def inner(*args, **kwargs):
res = func(*args, **kwargs)
return res
return inner
装饰器模板
1,无参装饰器
def outer(func):
def inner(*args,**kwargs)
res = func(*args,**kwargs)
return res
return inner
@outer
def func():
pass
func()
2.有参装饰器
def outer_pule(a,b):
def outer(func):
def inner(*args,**kwargs)
res = func(*args,**kwargs)
return res
return inner
return outer
@outer_pule(a,b)
def func():
pass
func()
多层装饰器
def outer1(func1):
print("from outer1")
def inner1(*args, **kwargs):
print("from inner1")
res1 = func1(*args, **kwargs)
return res1
return inner1
def outer2(func2):
print("from outer2")
def inner2(*args, **kwargs):
print("from inner2")
res2 = func2(*args, **kwargs)
return res2
return inner2
def outer3(func3):
print("from outer3")
def inner3(*args, **kwargs):
print("from inner3")
res3 = func3(*args, **kwargs)
return res3
return inner3
@outer1 # index = outer1(inner2) == inner1 func1 == inner2
@outer2 # outer2(inner3) == inner2 func2 = inner3
@outer3 # outer3(index) == inner3 func3 = index
def index():
print("from index")
index()
递归函数
1.什么是递归函数
递归函数就是函数体代码中又调用了其他函数,并且拥有一个明确的结束条件,这就是递归函数。
代码展示: def index(a):
if a == 1:
return 1
return index(a-1)
res = index(5)
print(res) # 16
二分法
1.什么是二分法
就是通过不断的一分而二 判断查询数据所在位置 ,然后再次一分为二的过程。
!!!必须满足列表为有序时才可以使用,从大到小或者从小到大
代码展示:
l1 = [1.2.3.4.5.6.22.33,44,123,234,355,6664,34534,234234,23423423]
find_num = 123 #要查询的数据可以随时改变
while 1:
mid_num = len(l1) //2 #查询列表中间数索引位置
if l1[mid_num] > find_num:
l1 = l1[:mid_num] #如果中间数比查询数大 则保留左边
elif l1[mid_num] < find_num:
l1 = l1 [mid_num+1:] #如果中间数比查询数小 则保留右边
elif li[mid_num] == fund_num:
break
#现在举例列表是升序,当然列表是降序也可以
三元表达式
格式
数据值1 if 条件 else 数值2
当条件满足 返回数据值1
当条件不满足 返回数据值2
生成式
列表生成式
l1 = [1, 2, 3]
l2 = [i+1 for i in l1]
print(l2) # [2, 3, 4]
"""for 加 if"""
l3 = [i for i in l1 if i == 1]
print(l3) # [1]
""" for 加 if 加 三元表达式"""
l4 = [i if i == 1 else "大佬" for i in l1 if i != 1]
print(l4) # ['大佬', '大佬']
字典生成式
l1 = "hello"
l1_dict = {i: k for i, k in enumerate(l1, 1)}
print(l1_dict) # {1: 'h', 2: 'e', 3: 'l', 4: 'l', 5: 'o'}
集合生成式
# 集合
l1 = "hello"
l1_set = {i for i in l1}
print(l1_set) # {'l', 'h', 'e', 'o'}
匿名函数
lambda 形参:返回值
内置函数
map() 映射
res = map(lambda x:x+1, l1)
max()/min() 最大最小值
l1 = [11, 22, 33, 44]
res = max(l1)
res = min(l1)
reduce() # 代表多个化为一个
res = reduce(lambda a, b: a * b, l1) # 计算 ((((1+2)+3)+4)+5)
zip() 拉链
#缝合多个列表的数据,将对应位置的元素组成一个小元组放到列表中。
l1 = [1, 2, 3, 4, 5]
l2 = ['a', 'b', 'c', 'd']
l3 = [11, 22, 33, 44, 55, 66]
res = zip(l1, l2, l3)
print(res) # <zip object at 0x00000222BA9E7280> 迭代器对象
print(list(res)) # [(1, 'a', 11), (2, 'b', 22), (3, 'c', 33), (4, 'd', 44)]
filter -过滤
1 = [11, 22, 33, 44, 55, 66, 77, 88]
res = filter(lambda x: x > 40, l1) #匿名函数x返回值x>40 遍历l1
print(list(res)) # [44, 55, 66, 77, 88]
sorted 升序
l1 = [13, 12, 533, 64, 766, 322, 131, 22]
res = sorted(l1)
print(res) # [12, 13, 22, 64, 131, 322, 533, 766]
asb - 代表数学中的绝对值
all() - 全是 用来元素类型是否都统一
any() - 全或 类似于:0 or 1 or 2 or 3 or 4
bytes - 用于类型转换
s1 = '最近缺觉'
print(bytes(s1, encoding='utf8'))
print(s1.encode('utf8'))
callable - 查询是否是函数或者类
name = 'leethon'
callable(name) # False
def index():
pass
callable(index) # True
# 无论是函数还是变量,都是名字形式的,就可以用此函数来判断。
chr\ord —— ASCII码值的数字字母对应转换
65-90 是A-Z,97-122 是a-z。
divmod - 整除和取余
divmod(100, 3) # (33, 1) 代码格式 100 整数3 得到除数和余数
enumerate - 枚举
通过遍历迭代器对象,得到一个序号与值的二元组迭代器。
list(enumerate([1, 2, 3, 4])) # [(0, 1), (1, 2), (2, 3), (3, 4)] 默认从0开始
# start参数,改变序号的开头
# 例子:ASCII表大写字母打印
l1 = [chr(i) for i in range(65, 91)]
print(list(enumerate(l1, start=65)))
[(65, 'A'), (66, 'B'), (67, 'C'), ……, (90, 'Z')]
hash - 哈希加密
print(hash('moon')) # -2441274338754145093
print(hash('123')) # -6488149301417385444
isinstance - 判断数据类型
isinstance(123,int) # True
isinstance([123],int) # False
#得到的结果是布尔值,待判断数据 加 类型
pow - 幂指数
用于计算数字次方
print(pow(3,3)) #3*3*3 = 27
round - 通常用于 四舍五入取整
print(round(99.499)) #99
print(round(99.5)) #100
sum - 求和
l1 = [1,2.3,2,23,1,23,1,23]
print(sum(l1)) # 76.3
常见内置函数
bin() 二进制
oct() 八进制
hex() 十六进制
eval() 可以执行字符串里的代码 但有一定逻辑的执行不了
exec() 可以执行有一定逻辑的字符串里的代码
chr() 可以字母转换成数字
ord() 可以数字转换从字母
id() 返回变量名的内存地址
input() 跟用户交互
print() 打印
int() 转换成整型
float() 转换成浮点型
bool() 转换成布尔值
list() 转换成列表
dict() 转换成字典
tuple() 转换成元组
set() 转换成集合
pow() 次方
open() 打开文件
round() 四舍五入
sum() 求和
enumerate() 枚举
bytes() 转换成二进制
all() 只要可迭代对象里有一个的布尔值是False则返回False
any()只要可迭代对象里有一个的布尔值True则返回True
可迭代对象
可迭代对象有:
str list dict tuple set 文件对象
可迭代对象特点:
都有对象内置__iter__方法
l1 = [1,2.3,2,23,1,23,1,23]
l2 = 'sdad'
l3 = {'a':'n'}
l1.__iter__()
l2.__iter__()
l3.__iter__()
可迭代的含义
迭代,依赖上一次的结果,来更新下一次。
l1 = [1,2.3,2,23,1,23,1,23]
res = l1.__iter__()
print(res.__next__())
print(res.__next__())
l2 = {'name':'moon','123':'321','222':'333'}
res = l2.__iter__()
print(res.__next__())
print(res.__next__())
# 先使用.__iter__() 把数据变为迭代器对象
#然后在使用.__next__() 进行迭代
迭代器
当变量名既有双下iter方法 也有 双下 next方法 那么这个就是迭代器
for循环的本质
for 变量名 in 可迭代对象\迭代器对象:
循环体代码
- 对in后面的对象执行`__iter__`方法得到迭代器对象
- while循环调用`__next__`取值,赋值给变量名
异常处理
语法错误
语法错误是明眼人一眼能够看出来的,语法这是程序员的基础技能,不容有错
逻辑错误
一眼可能看不出来,需要经验积累能感知到可能有的逻辑错误。
比方说,上文变量经过分支可能被赋值为一个字符串类型的数据,但是在后面执行了一个列表的内置方法报错了。
异常位置
异常类型
异常详情
解释器会只能的提示你 异常位置 在 哪 line 行 ,然后告诉你错误类型,还有该错误的解释