flask_caching 之 memoize 谜团

2019-12-25 17:29:59 +08:00
 l4ever
    # 缓存设置
    CACHE_TYPE = 'simple'
    # CACHE_TYPE = 'filesystem'
    # CACHE_THRESHOLD = 5000
    CACHE_DIR = './tmp/'
    CACHE_DEFAULT_TIMEOUT = 60 * 60 * 1
    @cache.memoize(timeout=7200)
    def get_token(self, secret):
        uri = f'{self.host}/gettoken?corpid={self.corpid}&corpsecret={secret}'
        res = http(uri) # 这里用 http 去统一处理. 
        token = res.get('access_token', '')

        if not token:
            errcode = res.get('errcode', '')
            errmsg = res.get('errmsg', '')
            current_app.logger.error(f'get_token error. errcode: {errcode}; errmsg:{errmsg}.')
        else:
            current_app.logger.debug(f'get_token success. token: {token}')
        return token

上例这样写没错吧? 问题是我在 http 请求函数里面打日志 每次都会进行请求

from flask_caching import Cache
from flask import Flask

app = Flask(__name__)

cache = Cache()
cache.init_app(app, config={
    "CACHE_TYPE": "simple"
})

def ab(dd):
    print('ab')
    return dd

@cache.memoize(timeout=30)
def sum_data(a, b):
    c = int(a) + int(b)
    c = ab(c)
    return c


@app.route('/')
def hello_world():
    return str(sum_data(1, 2))


if __name__ == "__main__":
    app.run(debug=True)

一气之下, 自己用官方的例子发现并不会重复输出 ab 有点费解. 哪里出错了.

3284 次点击
所在节点    Python
8 条回复
timonwong
2019-12-25 17:51:12 +08:00
KEY: instance method, the "self" varies
tmackan
2019-12-26 09:49:28 +08:00
@timonwong 有道理
tmackan
2019-12-26 09:50:38 +08:00
本地缓存都是根据参数,然后 hash 生成 redis 的 key,所以 self 这种场景不实用,参数不固定
tmackan
2019-12-26 09:53:04 +08:00
```
def memoize(obj):
"""
Local cache of the function return value
"""
cache = obj.cache = {}

@functools.wraps(obj)
def memoizer(*args, **kwargs):
key = str(args) + str(kwargs)
if key not in cache:
cache[key] = obj(*args, **kwargs)
return cache[key]
return memoizer
```
tmackan
2019-12-26 09:53:19 +08:00
def memoize(obj):
"""
Local cache of the function return value
"""
cache = obj.cache = {}

@functools.wraps(obj)
def memoizer(*args, **kwargs):
key = str(args) + str(kwargs)
if key not in cache:
cache[key] = obj(*args, **kwargs)
return cache[key]
return memoizer
limboMu
2019-12-26 15:16:39 +08:00
@tmackan 刚刚看完源码,作者对装饰方法的时候做了特殊处理,你要保障 get_id(self)的结果是一致的就好了
“”“
def get_id(obj):
return getattr(obj, "__caching_id__", repr)(obj)
”“”
tmackan
2019-12-26 20:08:48 +08:00
class CacheProperty(object):
"""
Decorator that converts a method with a single self argument into a
property cached on the instance.

Optional ``name`` argument allows you to make cached properties of other
methods. (e.g. url = cached_property(get_absolute_url, name='url') )
"""
def __init__(self, func, name=None):
self.func = func
self.__doc__ = getattr(func, '__doc__')
self.name = name or func.__name__

def __get__(self, instance, type=None):
if instance is None:
return self
res = instance.__dict__[self.name] = self.func(instance)
return res

class A(object):
@CacheProperty
def create(self, id):
return
lolizeppelin
2019-12-27 10:39:40 +08:00
处理 key generator

args = compat.inspect_getargspec(fn)
has_self = args[0] and args[0][0] in ('self', 'cls')
if has_self:
args = args[1:]


或者直接用 dogpile

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/632257

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX