本文主要是介绍python中的装饰器,函数带参数的装饰器,带类参数的装饰器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
其实,python 中的装饰器本质上就是一个函数,这个函数接收其他的函数作为参数,并将其以一个全新的修改后的函数替换它
关于装饰器的知识是python面试中比较常见的,对于装饰器的理解可以看这篇文章:理解Python中的装饰器,理解之后,再手写一遍下面的8种装饰器加深理解以后使用就更轻松多了!
1.最简单的函数
def myfunc()print "i am a function"myfunc()
2.初步了解装饰函数的调用结构
在函数执行前和执行后分别计时,打印函数运行消耗的时间
import datetime
import time
def out(fun):start = datetime.datetime.now()fun()end = datetime.datetime.now()print (end-start)return fun
def inner():time.sleep(1)print ("i am inner func")myfunc = outmyfunc(inner)
3.尝试引用@语法糖来调用装饰函数
import datetime,time
def out(func):start =datetime.datetime.now()func()end = datetime.datetime.now()print(end-start)return func@out
def myfunc():time.sleep(1)print("zhangkun inner")
4.使用内嵌的包装函数
使用内嵌包装函数来确保每次新函数都被调用,内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象
import datetime,timedef out(func):def inner():start = datetime.datetime.now()func()end = datetime.datetime.now()print(end-start)print("out and inner")return inner@out
def myfunc():time.sleep(1)print("zhangkun")myfunc()
5.对带参数的函数使用装饰器
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象
import datetime,timedef out(func):def inner(*args):start = datetime.datetime.now()func(*args)end = datetime.datetime.now()print(end-start)print("out and inner")return inner@out
def myfunc(*args):time.sleep(1)print("args is{}".format(args))myfunc("lalalal")
6.给装饰器参数
和上一示例相比在外层多了一层包装
#coding:utf-8
def outermost(*args):def out(func):print ("装饰器参数{}".format(args))def inner(*args):print("innet start")func(*args)print ("inner end")return innerreturn out@outermost(666)
def myfun(*args):print ("试试装饰器和函数都带参数的情况,被装饰的函数参数{}".format(args))myfun("zhangkun")
7.带类参数的装饰器
class locker:def __init__(self):print("locker.__init__() should be not called")@staticmethoddef acquire():print("locker.acquire() static method be called")@staticmethoddef release():print("locker.release() static method be called")def outermost(cls):def out(func):def inner():cls.acquire()func()cls.release()return innerreturn out@outermost(locker)
def myfunc():print("myfunc called")myfunc()
8.对一个函数应用多个装饰器
class mylocker:def __init__(self):print("mylocker.__init__() called.")@staticmethoddef acquire():print("mylocker.acquire() called.")@staticmethoddef unlock():print(" mylocker.unlock() called.")class lockerex(mylocker):@staticmethoddef acquire():print("lockerex.acquire() called.")@staticmethoddef unlock():print(" lockerex.unlock() called.")def lockhelper(cls):def _deco(func):def __deco2(*args, **kwargs):print("before %s called." % func.__name__)cls.acquire()try:return func(*args, **kwargs)finally:cls.unlock()return __deco2return _decoclass example:@lockhelper(mylocker)@lockhelper(lockerex)def myfunc2(self, a, b):print(" myfunc2() called.")print(a+b)a = example()
a.myfunc2(1,2)
9.作为一个类
虽然装饰器几乎总是可以用函数实现,但是在某些情况下,使用用户自定义的类可能会更好,如果装饰器需要复杂的参数化或者依赖特定状态,那么这种说法往往是对的
非参数化装饰器用作类的通用模式如下
class DerocatorAsClass:def __init__(self,funcation):self.funcation = funcationdef __call__(self, *args, **kwargs):# 调用函数之前,做点什么result = self.funcation(*args,**kwargs)# 在调用之后做点什么并且返回结果return result
这篇关于python中的装饰器,函数带参数的装饰器,带类参数的装饰器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!