目录
入门使用
我们先从最基本的开始,创建一个函数嵌套函数试试行不行,调用输出。成了!那我们再试试调用嵌套函数看看。
def First():
print("这是主函数!")
def First_1():
print('这是主函数嵌套的函数 First_1 ')
#我们在主函数里面调用嵌套函数
First_1()
First()
这是主函数! 这是主函数嵌套的函数 First_1
#然后我们在外面调用嵌套函数试试,发现报错了: 说明这个函数没有定义
First_1()
>>>
name 'First_1' is not defined
发现失败了,到这里我们可以发现在函数里面嵌套的函数其实跟局部变量差不多,作用域只在它所在函数里面,那我们是不是也可以将函数作为参数进行传递给函数呢?我们来进行以下测试。
#创建一个函数,参数为func,也就是函数
def Second(func):
print("下面的输出是调用func")
func()
#创建一个作为函数参数
def Cxk():
print('这是一个函数参数')
#我们来调用一下,看会发生什么
Second(Cxk)
哎,不出所料,被调用的函数成功进行了输出
>>>下面的输出是调用func
这是一个函数参数
函数是变量,那也就具备了一些变量的特性咯,比如返回变量?来试试!
#依旧是创建一个函数,参数为func,也就是函数
def Third(func):
print("下面返回func")
return func
#创建一个作为函数参数,并让它返回一串字符
def Cxk():
return '这是一个函数参数'
我们来调用一下,接收返回看会发生什么
a=Third(Cxk)
先看看接收到的返回a是什么类型
print(type(a),"这是Third函数调用Cxk函数进行的返回%s"%a)
这是输出>>>
下面返回func <class 'function'> 这是Third函数调用Cxk函数进行的返回<function Cxk at 0x000001445E5F1EA0>
依旧不出所料,能跟变量一样进行返回
>>>
下面返回func
<class 'str'> 这是Third函数调用Cxk函数进行的返回这是一个函数参数<function Cxk at 0x000001445E5F1EA0>
其实由此我们就已经创建了一个装饰器,下面我们来看看真正的装饰器是怎么样的。我们用一个例子来看看。
import time
def demo(fun):
"""
计算函数运行时间的装饰器
fun:函数
"""
def wrapper():
print('函数开始运行')
star_time=time.time() # 记录函数开始运行的时间
fun() # 运行的函数
end_time=time.time() # 记录函数运行结束后的时间
print('运行时间:%.8f' %(end_time-star_time)) # 打印出函数运行的时间
return wrapper
#我们创建一个生成列表并求和的函数
@demo
def new_list():
print(sum([x for x in range(0,101)]))
#我们直接运行这函数看看吧
new_list()
>>>
函数开始运行
5050
运行时间:0.00099754
不可思议!
我们不仅调用了new_list(),还调用demo()
观察以上例子,我们能发现什么?
一开始:以上我们对于函数的调用都是在调用最新的函数(比如:First,Second,Third),然后该函数再调用功能函数(比如:First_1,Cxk)
现在呢:我们直接调用功能函数,然后再调用最新的函数实现附加的功能
为什么我要叫最新的函数呢,因为这就是装饰器的一个作用,
当我们功能函数已经运行很久了,现在又想附加功能,我们只能去更改原函数,但有时候牵一发而动全身,
所以装饰器就出来了,我们创建最新的函数嵌套以前的功能函数岂不是直接实现了附加功能
那为什么会这样呢?
请看这个小东西@demo
@这叫修饰符,@ 符号就是装饰器的语法糖,它放在函数开始定义的地方,这样就可以省略最后一步再次赋值的操作。
这是网上的:
作用是为现有函数增加额外的功能,常用于插入日志、性能测试、事务处理等等。
创建函数修饰符的规则:
(1)修饰符是一个函数
(2)修饰符取被修饰函数为参数
(3)修饰符返回一个新函数
(4)修饰符维护被维护函数的签名
看得懂看不懂都没关系,只要记得这几个规则就行了,通俗的来讲,装饰装饰,意思上理解就是生活中小背包的一个饰品,让我们的书包看起来更美观,而饰品买包的时候是没有的,这是我们自己买来装上去的,所以说装饰器就是为函数实现不同的功能而创造的。这里我们的让包看起来更美观就是我们要实现的功能。
进阶使用
好了,现在我们已经基本了解什么叫装饰器了,那它有什么用呢?或者它用在什么地方?
其实上边也已经说了一些:插入日志、性能测试、事务处理等等。
带参数的装饰器
def demo(func):
new_number=3
def wrapper(*args,**kwargs): #装饰后的方法
print("函数开始运行")
sum_result=func(*args,**kwargs)
sum_result+=new_number
print('函数结束')
return sum_result
return wrapper
@demo
def add(a,b):
return a+b
add(1,2)
>>>
函数开始运行
函数结束
6
至此我们可以看见原函数只能进行两个数加减,我们添加一个功能,经过修饰器后我们给它添加了第三个数。那我们怎么不再函数内定义数,而直接给装饰器的语法糖上附带第三个数呢?源代码修改成以下
def demo(new_number):
def add_number(func):
def wrapper(*args,**kwargs): #装饰后的方法
print("函数开始运行")
sum_result=func(*args,**kwargs)
sum_result+=new_number
print('函数结束')
return sum_result
return wrapper
return add_number
#接收参数
@demo(new_number=3)
def add(a,b):
return a+b
add(1,2)
>>>
函数开始运行
函数结束
6