一. 函数的相关名称
1.函数的注释
def chi(food,drink):
"""
这里是函数的注释,先写一下当前这个函数是干什么的,比如我这个函数就是一个吃
:param food : 参数food是什么意思
:param drink:参数drink是什么意思
:return:返回的是什么东东
"""
print(food,drink)
return "very good"
2.如何获取到函数的相关信息
def chi(food,drink):
print(food,drink)
print(chi.__doc__) #获取函数的文档注释
print(chi.__name__) #获取到函数名称
chi("吃嘛嘛香","我不想吃")
函数名.__name__可以查看函数的名字
函数名.__doc__可以查看函数的文档注释
有一个例子我们可以看一看他的函数名:装饰器
def wrapper(func):
def inner(*args,**kwargs):
"""在执行目标函数之前要执行的内容"""
ret = func(*args,**kwargs)
"""在执行目标函数之后要执行的内容"""
return ret
return inner
@wrapper #语法糖
def target_func():
print("我是目标函数")
target_func()
print(target_func.__name__) #结果显示的是inner
我们虽然访问的是target_func函数,但是实际上执行的是inner函数.这样会给下游的程序员带来困惑.为了不让下游程序员有这样的困惑.我们需要把函数名修改一下.具体修改方案:
from functools import wraps #引入函数模块
def wrapper(func):
@wraps(func) #使用函数原来的名字
def inner(*args,**kwargs):
"""在执行目标函数之前要执行的内容"""
ret = func(*args,**kwargs)
"""在执行目标函数之后要执行的内容"""
return ret
return inner
@wrapper
def target_func():
print("我是目标函数")
target_func()
print(target_func.__name__) #不再是inner,而是target_func了
PS:*args和**kwargs什么时候打散,什么时候聚合
1.接收参数的时候是聚合,参数声明
2.传递参数的时候是打散,给函数传递实参
def wrapper(func):
@wraps(func)
def inner(*args,**kwargs): #这里是聚合
"""在执行目标函数之前要执行的内容"""
ret = func(*args,**kwargs) #这里是打散,这里的作用其实就是为了保证我可以装饰所有函数而准备的
"""在执行目标函数之后要执行的内容"""
return ret
return inner
三.装饰器传参
from functools import wraps
def wrapper_out(flag):
def wrapper(fn):
@wraps(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(False) #传递True和False来控制装饰器内部的运行效果
def yue():
print("呀呀呀呀呀呀呀呀")
yue()
注明:@wrapper_out(True)的执行步骤,先执行wrapper_out(True)然后再@返回值,返回值恰好是wrapper,结果就是@wrapper.
四.多个装饰器装饰同一个函数
我们先来看一个例子:
def wrapper1(fn):
def inner(*args,**kwargs):
print("111111")
ret = fn(*args,**kwargs)
print("222222")
return ret
return inner
def wrapper2(fn):
def inner(*args,**kwargs):
print("3333333")
ret = fn(*args,**kwargs)
print("444444444")
return ret
return inner
@wrapper2
@wrapper1
def eat():
print("我想吃水果")
eat()
打印的结果是:
33333333
111111111
我想吃水果
22222222
44444444
执行顺序:首先@wrapper1装饰起来,然后获取到一个新函数是wrapper1中的inner,然后执行@wrapper2,这个时候wrapper2装饰的就是wrapper1中的inner了.所以,执行顺序就像:第二层装饰器前(第一层装饰器前(目标)第一层装饰器后)第二层装饰器后.程序从左到右执行起来,就是我们看到的结果.
小知识点:
1.枚举
li = [1,2,3,4,5,6,7] #enumerate可以直接获取到索引和元素.
for e,i in enumerate(li):
print(e,i)
2.解码
s = "祝你生日快乐"
bys = s.encode("utf-8") #编码
print(bys)
s1 = bys.decode("utf-8") #解码
print(s1)
补充一点:utf-8不能直接转换成GBK,必须先转换成UNICOD之后在转换成GBK