python 装饰器常见场景与用法

1.计算程序耗时

def time_calc(func):

    def wrapper(*args, **kwargs):
        start_time = time.time()
        f = func(*args, **kwargs)
        cost_time = time.time() - start_time
        print("cost time is: ", cost_time)
        return f

    return wrapper

@time_calc
def multiply(a, b):
    return a * b

result = multiply(3, 4)
print("result is: ", result)

代码运行结果:

cost time is:  3.0994415283203125e-06
result is:  12

2.权限控制

user_age = 21

def authorize(func):

    def wrapper(*args, **kwargs):
        if user_age > 18:
            return func(*args, **kwargs)
        print("your age is too small, you can't play game!")

    return wrapper

@authorize
def play_game():
    print("this is interesting game!")

play_game()

3.打印日志

def logged(func):
    def print_log(*args, **kwargs):
        print(func.__name__ + " was used!")
        return func(*args, **kwargs)

    return print_log

@logged
def f(x):
    return x * x


result = f(5)
print("result is: ", result)

代码运行结果为:

f was used!
result is:  25

4.装饰器传参数

def setName(country):  # 带参数的装饰器,外头需要多套一层
    def wrapper(func):  # 接受函数对象作为参数,返回包装后的函数对象
        def decorator(*args, **kwargs):  # 具体包装过程
            if country == "American":
                print("American is in North America!")
            elif country == "China":
                print("China is in Asia!")
            elif country == "England":
                print("England is in Europe!")
            else:
                print("Unknwon!")
            return func(*args, **kwargs)

        return decorator

    return wrapper


@setName("American")
def func(name):
    return "Welcome %s" % name

result = func("LiLi")
print(result)
American is in North America!
Welcome LiLi

5.wraps装饰器

一个函数不止有执行语句,还有__name__,__doc__等等属性。加上装饰器以后,函数的属性会发生改变。

def authorize(func):

    def wrapper(*args, **kwargs):
        if user_age > 18:
            return func(*args, **kwargs)
        print("your age is too small, you can't play game!")

    return wrapper

@authorize
def play_game():
    print("this is interesting game!")

print(play_game.__name__)

因为装饰器返回了wrapper,替换了之前的play_game,因此函数名,文档等信息变成了wrapper函数下面的。
我们可以通过使用functools.wraps,这样可以消除装饰器对原函数造成的影响。wraps会将原函数的相关信息拷贝进去,最后装饰器不会修改原函数相关信息。

from functools import wraps

def authorize(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        if user_age > 18:
            return func(*args, **kwargs)
        print("your age is too small, you can't play game!")

    return wrapper

@authorize
def play_game():
    print("this is interesting game!")

print(play_game.__name__)

最后的结果为

play_game
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值