python全栈开发 * 12 知识点汇总 * 180530

 12  知识点总结  装饰器进阶
⼀. 通⽤装饰器的回顾
1.开闭原则: 对增加功能开放. 对修改代码封闭
2.装饰器的作⽤: 在不改变原有代码的基础上给⼀个函数增加功能
3.通⽤装饰器的写法:
def wrapper(fn):
def inner(*args,**kwargs):
print("目标函数前一行")
ret=fn(*args,**kwargs)
print("目标函数后一行")
return ret
return inner
@wrapper
def target_func(*args,**kwargs):
print("我是目标函数体")
target_func()
4.执⾏过程:
(1) 程序从上向下, 当执⾏到@wrapper的时候. 把函数作为参数传递给wrapper函数. 得到inner函数. 重新赋值给target_func
(2) 当执⾏到target_func的时候. 我们实际上执⾏的是inner函数. inner函数会先执⾏⽬标函数之前的代码. 然后再执⾏你的⽬标函数. 执⾏完⽬标函数最后执⾏的是⽬标函数
之后的代码
⼆. 函数的有⽤信息
1. 如何给函数添加注释 用三个引号来表示
def eat(food,drink):
""" eat:把传递进来的吃掉
:param food: 参数food是什么意思
:param drink: 参数drink是什么意思
:return: None 返回什么
"""
print(food,drink)
return "very good"
按住ctrl 点内置函数名,可以查看函数的注释如int,str 等
2.如何获取到函数的相关信息
def eat(food,drink):
"""
:param food: 参数food是什么意思
:param drink: 参数drink是什么意思
:return: None 返回什么
"""
print(food,drink)
# print(eat.__name__) 读取不出来
# print(eat.__doc__) 读取不出来
return "very good"
eat("水果","可乐")
print(eat.__name__) # 查询函数名
print(eat.__doc__) #查询函数文档注释

函数名.__name__可以查看函数的名字 (双下划线)
函数名.__doc__ 可以查看函数的⽂档注释
(1) 一个被装饰器装饰过的函数:查询目标函数的函数名
def wrapper(fn):
def inner(*args,**kwargs): # 聚合
print("目标函数前一行")
ret=fn(*args,**kwargs) # 打散 这⾥的作⽤. 其实就是为了保证我可以装饰所有函数⽽准备的
print("目标函数后一行")
return ret
return inner
@wrapper
def target_func(*args,**kwargs):
print("我是目标函数体")
target_func()
print(target_func.__name__) # 被装饰过的函数函数名是inner.
(2) 把上述查询函数名修改为原函数名
from functools import wraps # 加 引入函数模块
def wrapper(fn):
@wraps(fn) # 加 使用函数原来的名字
def inner(*args,**kwargs):
print("目标函数前一行")
ret=fn(*args,**kwargs)
print("目标函数后一行")
return ret
return inner
@wrapper
def target_func(*args,**kwargs):
print("我是目标函数体")
target_func()
print(target_func.__name__) # 查询结果不再是inner 而是target_func
@wrapper
def new_target_func():
print("我是另⼀个⽬标函数")
new_target_func()
print(new_target_func.__name__)
三.装饰器传参
def wrapper_out(flag):
def wrapper(fn):
def inner(*args,**kwargs):
if flag==True: # 设定条件,满足执行下一步
print("目标函数前一行")
ret=fn(*args,**kwargs)
print("目标函数后一行")
else: # 不满足执行这一步
ret=fn(*args,**kwargs)
return ret
return inner
return wrapper
@wrapper_out(True)
def target_func():
print("我是目标函数体")
target_func() # 目标函数前一行,我是目标函数体,目标函数后一行
@wrapper_out(False)
def target_func():
print("我是目标函数体")
target_func() # 我是目标函数体
执行步骤: 先执⾏wrapper(True) 然后再@返回值. 返回值恰好是wrapper. 结果就是@wrapper
四.多个装饰器装饰一个函数
def wrapper(fn):
def inner(*args,**kwargs):
print("我是a")
ret=fn(*args,**kwargs)
print("我是b")
return ret
return inner
def wrapper1(fn):
def inner(*args,**kwargs):
print("我是c")
ret=fn(*args,**kwargs)
print("我是d")
return ret
return inner
def wrapper2(fn):
def inner(*args,**kwargs):
print("我是e")
ret=fn(*args,**kwargs)
print("我是f")
return ret
return inner
@wrapper2
@wrapper1
@wrapper
def eat(*args,**kwargs):
print("我是目标函数")
eat()
执行步骤:
执⾏顺序:
⾸先@wrapper1装饰起来. 然后获取到⼀个新函数是wrapper1中的inner.
然后执⾏@wrapper2.这个时候. wrapper2装饰的就是wrapper1中的inner.

第⼆层装饰器前(第⼀层装饰器前(⽬标)第⼀层装饰器后)第⼆层装饰器后. 程序从左到右执⾏
五.补充知识点
1枚举 (同时拿元素和索引)
lst=["金","木","水","火","土"]
for index,element in enumerate(lst):
print(index,element) # 解构
for element in enumerate(lst):
print(element) # 结果是元组(0,"金)
2.存盘 , 网络传输
s="提前祝大家端午节快乐"
bys=s.encode("UTF-8") # 编码
print(bys) # 结果 字节
s1=bys.decode("UTF-8") # 解码
print(s1) # 结果 字符串
应用: 把UTF-8 转成 GBK
bys=b'\xe6\x8f\x90' # 一个字符的utf-8 形式
s=bys.decode("UTF-8") # 用UTF-8 解码成 字符串s
gbk=s.encode("GBK") # 再把字符串转化成GBK (两个字节)
print(gbk) # 结果 b'\xcc\xe1'
 


猜你喜欢

转载自www.cnblogs.com/J-7-H-2-F-7/p/9187974.html