保证在不改变原有函数结构的基础上,实现其功能的添加
即开放封闭原则:
- 开放:可以增加新的功能
- 封闭:原函数的代码不能修改
- 引入日志
- 函数执行时间统计
- 执行函数前的预处理
- 执行函数后的清理功能
- 权限检验
- 缓存
def decorater(func):
print('------>1')
def addfunc():
func()
print('------>3')
print('新增一个功能')
print('再新增一个功能')
print('------>4')
print('------2')
return addfunc
@decorater # 原理上等价于:oldfunc = decorater(oldfunc)
def oldfunc():
print('可以实现一个功能')
oldfunc()
------>1
------2
可以实现一个功能
------>3
新增一个功能
再新增一个功能
------>4
def decorater(func):
print('------>1')
def addfunc(para1): # 带参数的被修饰函数,需要在此添加参数
func(para1)
print('------>3')
print('新增一个功能')
print('再新增一个功能')
print('------>4')
print('------2')
return addfunc
@decorater
def oldfunc(para1):
print('可以实现一个{}功能'.format(para1))
oldfunc('收费') # 这里oldfunc本质就是addfunc
------>1
------2
可以实现一个收费功能
------>3
新增一个功能
再新增一个功能
------>4
def decorater(func):
def addfunc(*args, **kwargs):
func(*args, **kwargs)
print('略写')
return addfunc
@decorater # 原理上等价于:oldfunc = decorater(oldfunc)
def oldfunc(para1):
print('可以实现一个{}功能'.format(para1))
@decorater # 原理上等价于:oldfunc = decorater(oldfunc)
def oldfunc1(para1, para2):
print('可以实现一个{}功能,预计花费{}元'.format(para1, para2))
@decorater # 原理上等价于:oldfunc = decorater(oldfunc)
def oldfunc2(para1, para2, para3=3):
print('可以实现一个{}功能,预计花费{}元,用时{}天'.format(para1, para2, para3))
oldfunc('收费')
oldfunc1('收费', 1000)
oldfunc2('收费', 1000)
oldfunc2('收费', 1000, para3=4)
可以实现一个收费功能
略写
可以实现一个收费功能,预计花费1000元
略写
可以实现一个收费功能,预计花费1000元,用时3天
略写
可以实现一个收费功能,预计花费1000元,用时4天
略写
def decorater(func):
def addfunc(*args, **kwargs):
func(*args, **kwargs)
print('略写')
return '实际花费了10天'
return addfunc
@decorater # 原理上等价于:oldfunc = decorater(oldfunc)
def oldfunc2(para1, para2, para3=3):
print('可以实现一个{}功能,预计花费{}元,用时{}天'.format(para1, para2, para3))
result = oldfunc2('收费', 1000, para3=4) # 等价于:oldfunc2 = addfunc
print(result)
可以实现一个收费功能,预计花费1000元,用时4天
略写
实际花费了10天
https://www.runoob.com/python3/python3-func-open.html
https://www.runoob.com/python/python-func-open.html
os、open()
相对路径和绝对路径
仅读取–文本
with open(path + '\\调用文件\\2020_理科.txt', 'r') as f: for line in f.readlines(): line_info = line.strip().split(",") info_fenshu_2020_like.append(line_info[0]) info_renshu_2020_like.append(line_info[1]) info_paiming_2020_like.append(line_info[2])
追加写–文本
with open(os.getcwd() + './存储下载文件/小说/{}.txt'.format(book_name), mode='a+', encoding='utf-8') as f: f.write('**********************\n') f.write('**********************\n') f.write('{}\n'.format(title)) f.write('**********************\n') f.write('**********************\n') f.write('\n\n\n') f.write(content) f.write('\n\n\n\n')
写–二进制文件
with open(path + '//存储下载文件//网易下载歌曲//{}.mp3'.format(name), 'wb') as f: f.write(response.content) f.flush()
跳过第一行非数据信息
with open('test.txt') as f: print(f.readlines()) with open('test.txt') as f: print(f.readline(), end='') next(f) # 此命令可以保证跳过一行操作 print(f.readline(), end='')
[‘wer\n’, ‘aer\n’, ‘awre’]
wer
awre
语法错误:编写代码的时候可以人为检查
异常:出现在运行之后,通常是xxxError
有些异常不是程序的问题,而是输入不在程序正常运行的范围内。
这种情况可以通过异常处理来进行提示
一个父异常下面可能包含很多个子异常
except异常处理是按照顺序,代码从上到下运行
所以父异常必须放在子异常后边
try: expression except 子子异常: # 子子异常是子异常1或子异常2的子异常 expression0 except 子异常2: # 子异常1、子异常1两者并列,属于父异常 expression1 except 子异常1: expression2 except 父异常 as err: print('异常是:', err) # 可以获得错误的具体内容 expression3
基本
try: expression except Error1: expression1 ---------------可添加部分--------------- except Error2: expression2 except Error3: expression3 ................... ---------------可添加部分---------------
try - except - else
try: expression except Error3: expression3 # 有else,表达式就不能出现return else: # 没有异常,才会执行else的内容 expression
try - except - finally
try: expression except Error3: expression3 # 有finally,即使里面有return,也会执行finally的内容 finally: # 有没有异常,都会执行,常用于f.close() expression
有时候你需要判断代码的输入是否符合要求,并作相应处理
就可以抛出一个自定义的异常或者已有的异常机制
配合异常处理机制来明确问题所在
'''
expression
'''
raise Exception('字符长度异常')
raise NameLensError('名字不合要求')
列表推导式
[表达式 (变量) for 变量 in 旧列表]
[表达式 (变量) for 变量 in 旧列表 if 条件]
[x*x for x in range(6)] [x*x for x in range(9) if x % 2 ==0] names = ['lily', 'rouse', 'jack', 'Tom'] newname = [name for name in names if len(name)>3] print(newname) newname = tuple([name.upper() for name in names if len(name)>3]) print(newname)
[‘lily’, ‘rouse’, ‘jack’]
(‘LILY’, ‘ROUSE’, ‘JACK’)双重循环
suit = ['♥','♦','♣','♠'] face = ['A','2','3','4','5','6','7','8','9','10','J','Q','K'] poke = [(x,y) for x in suit for y in face]
字典推导式
# 列表生成式可以使用两个变量,实现字典的键值交换 d = {"X":"A","Y":"B","Z":"C"} list5 = {v:k for k,v in d.items()} print(list5)
集合推导式
{x for x in range(10)}
列表推导式可以直接创建一个列表
如果列表内容很大,且只需要前边部分数据,这样就非常占用空间。
可以用生成器generator来解决这个问题
通过某种算法推算列表元素,在循环中不断推算后续元素,就不需要创建列表,从而节省大量空间
这种一边循环一边计算的机制,就是生成器
通过推导式生成
gener = (x * 3 for x in range(20)) print(type(gener))
调用
gener = (x * 3 for x in range(20)) print(type(gener)) print(gener.__next__()) print(next(gener))
0
3超出数据量后就会抛出异常,可用异常处理机制避免这个
通过函数生成
def generator(): # 1.定义函数表达式 x = 0 while True: x += 1 yield x # 2.使用yiled关键字,生成器返回x的值。yield相当于 return+暂停功能 g = generator() # 3.调用,就是生成器了 print(type(g)) print(next(g)) print(next(g)) g = generator() # 重新生成,再调用 print(next(g)) print(next(g)) g = generator() # 重新生成,再调用 t1 = g.send(None) # send的更多作用后边单列讲解 t2 = g.send(1) # 调用send必须赋参数 print(t1, t2)
1
2
1
2
1 2
send()函数
def genera(): n = 0 while True: temp = yield n for i in range(temp): print('----->', i) n += 1 g = genera() print(g.send(None)) # 第一次调用,必须赋予参数None print(g.send(5)) # send函数把5传给temp,然后g.send(5)的返回值是n print(g.send(4)) # 同理
0
-----> 0
-----> 1
-----> 2
-----> 3
-----> 4
1
-----> 0
-----> 1
-----> 2
-----> 3
2
迭代是访问集合元素的一种方式
可以用isinstance()函数判断对象是否可迭代
from collections import Iterable list1 = [1, 2, 3, 4] strs = 'abc' ints = 100 print(isinstance(list1, Iterable)) print(isinstance(strs, Iterable)) print(isinstance(ints, Iterable))
True
True
False不可迭代:int型数据
可迭代:元组、列表、集合、字典、字符串、生成器
可以被next()函数调用并不断返回下一个值的对象称为迭代器
是一个可以记住遍历的位置的对象
迭代器对象从集合第一个元素开始访问,直到所有元素被访问结束
gener = (x * 3 for x in range(20)) print(type(gener)) print(next(gener)) # 生成器就是迭代器的一种
迭代器是一个大类,其定义为:
可以被next()函数调用并不断返回下一个值的对象称为迭代器
其内部包含生成器
生成器可以直接迭代,直接使用next函数
还包括list、tuple、set等一系列的 “可迭代对象”
可迭代对象不可直接迭代,即不能直接调用next()函数
【是否可迭代用isinstance()函数判断】
上述可迭代对象可以使用iter()函数,使得可迭代对象变为迭代器,从而调用next()函数
list1 = [1, 2, 3, 4] list1 = iter(list1) print(next(list1)) print(next(list1))
1
2
总的来说迭代器包含两大类
一类是生成器,可以直接迭代,生成器本身属于迭代器的一种
一类是可以通过iter()函数变为迭代器的可迭代对象