Python装饰器

2020年10月29日 11:45:39

“”“装饰器的作用:
1、调用原函数
2、为其增加新功能”""

第一步:

def wrapper(*args, **kwargs):
    res = func(*args, **kwargs)
    return res

第二步:

def outter(func):
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        return res
    return wrapper

第三步:增加新功能

def timer(func):
    def wrapper(*args, **kwargs):
        start = timer.time()
        res = func(*args, **kwargs)
        stop = timer.time()
        print(stop - start)
        return res
    return wrapper

作业:

“认证功能”,在确认用户名和密码后再执行

def auth(func):
    def wrapper(*args, **kwargs):
        name = input("your name:").strip()
        pwd = input("your password:").strip()
        if name == "egon" and pwd == "123":
            res = func(*args, **kwargs)
            return res
        else:
            print("账户密码错误")
    return wrapper


@auth
def index():
    print("from index")


index()

运行结果:

your name:ook
your password:123
账户密码错误

或者

your name:egon
your password:123
from index

----------------------分界线--------------------

扩展

1、 outter, timer, wrapper, auth是什么?是一个个名字,名字指向的就是内存地址。

2、名字后面加括号(),就会触发代码的运行。例如:

3、@print 等于 print(home) --> home这个名字指向的是 home函数的内存地址

@print
def home(a, b, c):
    pass

运行结果:

<function home at 0x7f95e30ccf28>

经过上面的优化后发现,print(index)的时候,
可以发现结果是 wrapper的内存地址,而不是原函数index的内存地址,
原函数的文档注释也无法显示出来,所以需要再修改一下。

def timer(func):
    def wrapper(*args, **kwargs):
        start = timer.time()
        res = func(*args, **kwargs)
        stop = timer.time()
        print(stop - start)
        return res
    wrapper.__name__ = func.__name__
    wrapper.__doc__ = func.__doc__
    return wrapper


@timer    # index = timer(index)
def index(x, y):
    """这个是主页功能"""
    print(x, y)


print(index.__name__)
print(index.__doc__)    # help(index) 这两个都是查看函数注释的功能

运行结果:

index
这个是主页功能

修改

手动将原函数的属性赋值给wrapper函数,肯定会有遗漏,所以需要调用一个模块,这是python提供的一个装饰器。
目的:将原函数的属性都覆盖给wrapper

from functools import wraps

def outter(func):
    @wraps(func)
    def wrapper():
        XXX
    return wrapper

有参装饰器(套了三层的函数)

‘’’
第二层函数outter的参数(func)是为了获取原函数的内存地址,
因为 语法糖 的原因,参数只能唯一, @outter ==> func = outter(func)
第一层函数wrapper的参数(*args, **kwargs) 是为了获取原函数的参数
所以,第一、二层的参数不能改动
所以,当需要其他参数时,就要第三层函数了
‘’’

有参装饰器模板

def 名为ABC的有参装饰器 (x, y, z):    # 参数可以有多个
    def outter(func):
        def wrapper(*args, **kwargs):
            res = func(*args, **kwargs)
            return res
        return wrapper
    return outter


@ABC(1,  y = 2, z = 3)
def 被装饰对象():
    pass
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值