2018-11-01
阅读量:
911
怎们用类写装饰器
下面用常见的写法实现了一个缓存装饰器。
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






评论(0)


暂无数据
推荐帖子
0条评论
0条评论
1条评论