python装饰器详解 带参数,python装饰器详解@static
python装饰器详解
python decorator的详细分析
什么是装饰器?
推荐:Python视频教程
Python decorators是一种用来扩展原函数的函数,目的是在不改变原函数名(或类名)的情况下,给函数增加新的函数。
这个函数的特别之处在于,它的返回值也是一个函数,是一个嵌入了“原”函数的函数。
一般来说,如果我们要扩展原有的功能代码,最直接的方法就是入侵代码并对其进行修改,例如:
导入时间
def f():
打印(“你好”)
时间.睡眠(1)
打印(“世界”)
这是我们的原始函数,然后我们试着记录这个函数的总执行时间。最简单的方法是修改原始代码:
导入时间
def f():
start_time=time.time()
打印(“你好”)
时间.睡眠(1)
打印(“世界”)
end_time=time.time()
执行时间=(结束时间-开始时间)*1000
打印(时间为%d毫秒 %execution_time )
但在实际操作中,有时核心代码无法直接更改,我们可以在不更改原代码的情况下定义另一个函数。(但是该功能需要再次执行才能生效)
导入时间
def deco(func):
start_time=time.time()
f()
end_time=time.time()
执行时间=(结束时间-开始时间)*1000
打印(时间为%d毫秒 %execution_time )
def f():
打印(“你好”)
时间.睡眠(1)
打印(“世界”)
if __name__==__main__:
装饰(f)
print(f.__name__ is ,f.__name__)
打印()
这里我们定义一个函数deco,它的参数是一个函数,然后把计时函数嵌入到这个函数中。但是要扩展这一千万个函数功能,
就是执行deco()函数千万次,所以这是不理想的!接下来,我们可以尝试用装饰器来实现它。我们先来看看装修工的原貌。
导入时间
def装饰(f):
定义包装():
start_time=time.time()
f()
end_time=time.time()
执行时间=(结束时间-开始时间)*1000
打印(时间为%d毫秒 %execution_time )
返回包装
@deco
def f():
打印(“你好”)
时间.睡眠(1)
打印(“世界”)
if __name__==__main__:
f()
这里的deco函数是最原始的装饰器。它的参数是函数,然后返回值也是函数。
作为参数的函数f()在返回函数包装器()内部执行。然后在函数f()前面加上@deco,
f()函数相当于被注入了定时函数。现在只要调用f(),就变成了“新函数更多”的函数。
(不需要重复原来的功能)。
1:具有固定参数的装饰器
导入时间
def装饰(f):
定义包装(a,b):
start_time=time.time()
女(阿,乙)
end_time=time.time()
execution_time = (end_time - start_time)*1000
print("time is %d ms" % execution_time)
return wrapper
@deco
def f(a,b):
print("be on")
time.sleep(1)
print("result is %d" %(a+b))
if __name__ == '__main__':
f(3,4)扩展2:无固定参数的装饰器
import timedef deco(f):
def wrapper(*args, **kwargs):
start_time = time.time()
f(*args, **kwargs)
end_time = time.time()
execution_time_ = (end_time - start_time)*1000
print("time is %d ms" %execution_time)
return wrapper
@deco
def f(a,b):
print("be on")
time.sleep(1)
print("result is %d" %(a+b))
@deco
def f2(a,b,c):
print("be on")
time.sleep(1)
print("result is %d" %(a+b+c))
if __name__ == '__main__':
f2(3,4,5)
f(3,4)
扩展3:使用多个装饰器,装饰一个函数
import timedef deco01(f):
def wrapper(*args, **kwargs):
print("this is deco01")
start_time = time.time()
f(*args, **kwargs)
end_time = time.time()
execution_time = (end_time - start_time)*1000
print("time is %d ms" % execution_time)
print("deco01 end here")
return wrapper
def deco02(f):
def wrapper(*args, **kwargs):
print("this is deco02")
f(*args, **kwargs)
print("deco02 end here")
return wrapper
@deco01
@deco02
def f(a,b):
print("be on")
time.sleep(1)
print("result is %d" %(a+b))
if __name__ == '__main__':
f(3,4)
'''装饰器调用顺序this is deco01
this is deco02
hello,here is a func for add :
result is 7
deco02 end here
time is 1003 ms
deco01 end here
'''
装饰器是可以叠加使用的,那么使用装饰器以后代码是啥顺序呢?
对于Python中的”@”语法糖,装饰器的调用顺序与使用 @ 语法糖声明的顺序相反。
在这个例子中,”f(3, 4) = deco01(deco02(f(3, 4)))”。
Python内置装饰器
在Python中有三个内置的装饰器,都是跟class相关的:staticmethod、classmethod 和property。
staticmethod 是类静态方法,其跟成员方法的区别是没有 self 参数,并且可以在类不进行实例化的情况下调用
classmethod 与成员方法的区别在于所接收的第一个参数不是 self (类实例的指针),而是cls(当前类的具体类型)
property 是属性的意思,表示可以通过通过类实例直接访问的信息
对于staticmethod和classmethod这里就不介绍了,通过一个例子看看property。
注意,对于Python新式类(new-style class),如果将上面的 “@var.setter” 装饰器所装饰的成员函数去掉,则Foo.var 属性为只读属性,使用 “foo.var = ‘var 2′” 进行赋值时会抛出异常。但是,对于Python classic class,所声明的属性不是 read-only的,所以即使去掉”@var.setter”装饰器也不会报错。
总结
本文介绍了Python装饰器的一些使用,装饰器的代码还是比较容易理解的。只要通过一些例子进行实际操作一下,就很容易理解了。以上就是python 装饰器详解的详细内容,更多请关注盛行IT软件开发工作室其它相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。