python 装饰器

1 函数装饰器

构成:外部函数传入被装饰函数名,内部函数返回装饰函数名
特点:不修改函数的调用方式,不修改函数的代码
作用:在不对函数做任何修改的情况下增加额外的功能
例如:缓存装饰器,权限验证装饰器,日志装饰器,路由装饰器,异常处理装饰器,错误重试装饰器,计时装饰器等
函数装饰器装饰函数
import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res=func(*args,**kwargs)  #如果被装饰函数有返回值,那么用res接收并return
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
        return res  
    return wrapper
@timmer
def add(a,b):
    return a+b
print(add(1,2))
print(add.__name__) #返回wrapper,被装饰的函数已经不再是它本身了 add=timmer(add),timmer方法返回的就是wrapper函数

函数装饰器装饰类

def Single(cls):
    clses = {}

    def single(*args, **kwargs):
        if cls not in clses:
            clses[cls] = cls(*args, **kwargs)
        return clses[cls]
    return single

@Single
class Food:
    def __init__(self,name):
        self.name = name

a = Food('红薯') 
b = Food('萝卜')
print(a==b)# True
print(a is b)# True
print(Food.__name__)#single,原理同上

函数装饰器的执行过程,我们修改一下示例1 。

def timmer(func):
    print('外部函数 功能1')
    def wrapper(*args,**kwargs):
        print('内部函数 功能1')
        res=func(*args,**kwargs)
        print('内部函数 功能2')
        return res
    print('外部函数 功能2')
    return wrapper
@timmer
def add(a,b):
    return a+b
#直接运行代码,结果:

外部函数 功能1
外部函数 功能2   可以看出在我们没有调用add方法的时候print已经生效了,这更说明被装饰的函数已经不再是他本身了

add(2,3)

外部函数 功能1
外部函数 功能2
内部函数 功能1
内部函数 功能2   综合两个结果可以看出是先执行外部函数,返回内部函数wrapper,然后执行wrapper

再看一个例子:

def timmerA(func):
    print('A外部函数 功能1')
    def wrapperA(*args,**kwargs):
        print('A内部函数 功能1')
        res=func(*args,**kwargs)
        print('A内部函数 功能2')
        return res
    print('A外部函数 功能2')
    return wrapperA
def timmerB(func):
    print('B外部函数 功能1')
    def wrapperB(*args,**kwargs):
        print('B内部函数 功能1')
        res=func(*args,**kwargs)
        print('B内部函数 功能2')
        return res
    print('B外部函数 功能2')
    return wrapperB
@timmerB
@timmerA
def add(a,b):
    return a+b
print(add(1,2))

结果如下:

A外部函数 功能1
A外部函数 功能2  #先运行A装饰器外部函数
B外部函数 功能1  #然后运行B装饰器外部函数
B外部函数 功能2  
B内部函数 功能1  #此时根据我们上个示例,应该运行被装饰函数,此时 add = wrapperB(wrapperA(add)) 这样应该就比较好理解了
A内部函数 功能1  
A内部函数 功能2
B内部函数 功能2

 

2 类装饰器

类装饰器主要是通过类的__call__方法来实现的

类装饰器装饰函数

class Foo(object):
    def __init__(self, func):
        self._func = func
      
def __call__(self): print('class decorator runing') self._func() print('class decorator ending') @Foo def bar(): print('bar') bar() print(bar.__name__) #报错,'Foo' object has no attribute '__name__'
#举个例子
class A:
def __init__(self):
pass
a = A()
print(a.__name__) # A instance has no attribute '__name__'

类装饰器装饰类

class Foo(object):
    def __init__(self, cls):
        self.cls = cls

    def __call__(self,name):
        s = self.cls(name)
        s.color = '红色'
        return s

@Foo
class Food:
    def __init__(self,name):
        self.name = name

a = Food('红薯')
print(a.name)
print(a.color)
print(Food.__name__)

 

 

 

转载于:https://www.cnblogs.com/tigerzhouv587/p/11310650.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值