python3装饰器例子_Python装饰器几个有用又好玩的例子

装饰器是一种巧妙简洁的魔术,类似于Java中的面向切面编程,我们可以再函数执行前、执行后、抛出异常时做一些工作。利用装饰器,我们可以抽象出一些共同的逻辑,简化代码。而简化代码的同时,就是在增加代码鲁棒性。

一、缓存

# coding:utf8

import time

import json

"""

简单的内存缓存参数

"""

def simple_cache(timeout=3):

def decorator(f):

def ff(*args, **kwargs):

arg = json.dumps([args, kwargs])

res = None

key = f.__module__ + f.__name__ + arg

if hasattr(f, key):

res = getattr(f, key)

if time.time() - res['last_time'] > timeout:

res = None

if res is None:

res = {'last_time': time.time(), 'data': f(*args, **kwargs)}

setattr(f, key, res)

return res['data']

return ff

return decorator

if __name__ == '__main__':

@simple_cache(timeout=3)

def haha(user_id):

print("haha", user_id)

@simple_cache(timeout=3)

def baga(user_id):

print("baga", user_id)

haha(0)

baga(0)

haha(0)

haha(1)

time.sleep(5)

haha(1)

二、重试

在进行网络请求时,我们常常需要重试几次才能请求成功。这种套路经常使用,却又嵌套的非常丑陋。此时,我们可以用装饰器将重试逻辑抽象出来。

def retry(count=1):

def dec(f):

def ff(*args, **kwargs):

ex = None

for i in range(count):

try:

ans = f(*args, **kwargs)

return ans

except Exception as e:

ex = e

raise ex

return ff

return dec

db = []

@retry(count=10)

def until_six():

db.append("haha")

print("until_six")

return db[6]

print(until_six())

三、兼容旧版参数

库都是随着时间变化而不断丰富的,函数的参数有可能发生变化,使用注解可以简洁完美地兼容旧版本。

lib.py

def add(x, y):

return x + y

haha.py

from lib import add

z = add(x=4, y=5)

print(z)

现在库函数add需要把x变成one,y变成two,同时需要保持haha.py正常运行。 lib.py

change_list = { # 存放函数名称变化表,统一维护

'add': {

'x': 'one',

'y': 'two',

}

}

def legacy(f):

def ff(*args, **kwargs):

if f.__name__ in change_list:

for old_arg, new_arg in change_list[f.__name__].items():

if new_arg not in kwargs and old_arg in kwargs:

kwargs.update({new_arg: kwargs.get(old_arg)})

del kwargs[old_arg]

print(kwargs)

return f(**kwargs)

return ff

@legacy

def add(one, two, **kwargs):

return one + two

这种方式可以把API的全部变化放到一个统一的配置文件里面,当决定不再支持旧版时,直接从配置文件里面把旧版参数删除掉即可。

四、deprecated

import logging

def deprecated(info):

def decorator(f):

def ff(*args, **kwargs):

logging.warning("%s is deprected. %s" % (f.__name__, info))

res = f(*args, **kwargs)

return res

return ff

return decorator

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值