Memoization(一种缓存技术)

请参看 memoize()

在memoization中,函数参数同样包含cache_key。

Note

如果函数不接受参数的话,cached()memoize() 两者的作用是一样的。

Memoize同样也为类成员函数而设计,因为它根据 identity 将 ‘self’ 或者 ‘cls’ 参数考虑进作为缓存键的一部分。

memoization背后的理论是:在一次请求中如果一个函数需要被调用多次,它只会计算第一次使用这些参数调用该函数。例如,存在一个决定用户角色的 sqlalchemy对象,在一个请求中可能需要多次调用这个函数。为了避免每次都从数据库获取信息,你可以这样做:

  1. class Person(db.Model):
  2. @cache.memoize(50)
  3. def has_membership(self, role_id):
  4. return Group.query.filter_by(user=self, role_id=role_id).count() >= 1

Warning

使用可变对象(例如类)作为缓存键的一部分是十分棘手的。建议最好不要让一个对象的实例成为一个memoized函数。然而,memoize在处理参数的时候会执行repr(),因此如果一个对象有__repr__函数,并且返回一个唯一标识该对象的字符串,它将能够作为缓存键的一部分。

例如,一个sqlalchemy person对象,它返回数据库的ID作为唯一标识符的一部分:

  1. class Person(db.Model):
  2. def __repr__(self):
  3. return "%s(%s)" % (self.__class__.__name__, self.id)

删除memoize的缓存

New in version 0.2.

在每个函数的基础上,您可能需要删除缓存。使用上面的例子,让我们来改变用户权限,并将它们分配到一个角色,如果它们新拥有或者失去某些成员关系,现在你需要重新计算。你能够用 delete_memoized() 函数来达到目的:

  1. cache.delete_memoized('user_has_membership')

Note

如果仅仅只有函数名作为参数,所有的memoized的版本将会无效的。然而,您可以删除特定的缓存提供缓存时相同的参数值。在下面的例子中,只有 user 角色缓存被删除:

  1. user_has_membership('demo', 'admin')
  2. user_has_membership('demo', 'user')
  3. cache.delete_memoized('user_has_membership', 'demo', 'user')