装饰器

本文深入探讨了Python装饰器的原理及应用,包括基本装饰器、带参数装饰器、基于类的装饰器等多种类型,并通过实例展示了如何使用装饰器进行函数增强。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原地址:https://zhuanlan.zhihu.com/p/65968462

import time

#装饰函数
def logger(func):
    def wrapper(*args,**kw):
        print("我要开始运行:{}函数了".format(func.__name__))

        #真正执行的是这行
        func(*args,**kw)

        print("运行完成!")
    return wrapper


@logger
def add(x,y):
    print(x,'+',y,' = ',x+y)

def timer(func):
    def wrapper(*args,**kw):
        t1 = time.time()

        #真正执行的地方
        func(*args,**kw)
        t2 = time.time()

        #计算时长
        costTime = t2 - t1
        print("花费时间:",costTime)
    return wrapper

@timer
def wantSleep(sleepTime):
    time.sleep(sleepTime)

'''
带参数的装饰器
'''
def sayHello(country):
    def wrapper(func):
        def deco(*args,**kw):
            if country == '中国':
               print( '你好!')
            elif country == 'american':
                print( 'Hello!')
            else:
                return

            #真正执行函数的地方
            func(*args,**kw)
        return deco
    return wrapper

@sayHello('中国')
def chinese():
    print('我是中国人!')

@sayHello('american')
def american():
    print('I am american!')


'''
基于类实现的装饰器
必须实现__call__ 和 __init__两个内置函数
__call__:接受被装饰函数
__init__:实现装饰逻辑
'''
class logger():
    def __init__(self,func):
        self.func = func

    def __call__(self,*args,**kw):
        print(self.func.__name__,"() is running!")

        return self.func(*args,**kw)

@logger
def say(something):
    print("say ",something)

say('hello!')

'''
带参数的类装饰器
__init__:接受参数
__call__:接受被装饰函数,完成装饰逻辑
'''
class logger():
    def __init__(self,level='INFO'):
        self.level = level

    def __call__(self,func):
        def wrapper(*args,**kwargs):
            print("[{level}]: the function {func}() is running..." \
                  .format(level=self.level, func=func.__name__))

            func(*args,**kwargs)
        return wrapper



@logger(level='WARNING')
def say(something):
    print("say ",something)

say('hello!')

'''
返回的名字都是innerFunc
是因为执行wrapped 与执行wrapper(wrapped)是等价的
所以名字也是等价的
'''
def wrapper(func):
    def innerFunc():
        pass
    return innerFunc

@wrapper
def wrapped():
    pass

print(wrapper(wrapped).__name__,wrapped.__name__)

'''
解决这个问题,使用functools中的wraps装饰器,它的作用就是将
被装饰的函数wrapped的一些属性赋值给装饰器函数wrapper,最终让属性的显示更加符合我们的直觉
'''
from functools import wraps
def wrapper(func):
    @wraps(func)
    def innerFunc():
        pass
    return innerFunc

@wrapper
def wrapped():
    pass

print(wrapped.__name__,wrapper(wrapped).__name__)



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值