291294878

2018-11-01   阅读量: 712

Python编程 数据分析师

怎们用类写装饰器

扫码加入数据分析学习群

下面用常见的写法实现了一个缓存装饰器。

def cache(func):
data = {}
def wrapper(*args, **kwargs):
key = f'{func.__name__}-{str(args)}-{str(kwargs)})'
if key in data:
result = data.get(key)
print('cached')
else:
result = func(*args, **kwargs)
data[key] = result
print('calculated')
return result
return wrapper

看看缓存的效果。

@cache
def rectangle_area(length, width):
return length * width
rectangle_area(2, 3)
# calculated
# 6
rectangle_area(2, 3)
# cached
# 6

装饰器的@cache是一个语法糖,相当于func = cache(func),如果这里的cache不是一个函数,而是一个类又会怎样呢?定义一个类class Cache, 那么调用func = Cache(func)会得到一个对象,这时返回的func其实是Cache的对象。定义__call__方法可以将类的实例变成可调用对象,可以像调用函数一样调用对象。然后在__call__方法里调用原本的func函数就能实现装饰器了。所以Cache类也能当作装饰器使用,并且能以@Cache的形式使用。

接下来把cache函数改写为Cache类:

class Cache:
def __init__(self, func):
self.func = func
self.data = {}
def __call__(self, *args, **kwargs):
func = self.func
data = self.data
key = f'{func.__name__}-{str(args)}-{str(kwargs)})'
if key in data:
result = data.get(key)
print('cached')
else:
result = func(*args, **kwargs)
data[key] = result
print('calculated')
return result

再看看缓存结果,效果一样。

@Cache
def rectangle_area(length, width):
return length * width
rectangle_area(2, 3)
# calculated
# 6
rectangle_area(2, 3)
# cached
# 6
添加CDA认证专家【维克多阿涛】,微信号:【cdashijiazhuang】,提供数据分析指导及CDA考试秘籍。已助千人通过CDA数字化人才认证。欢迎交流,共同成长!
0.0000 0 2 关注作者 收藏

评论(0)


暂无数据

推荐课程

推荐帖子