Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使django中的@cached_属性无效_Python_Django_Django Models_Django Views - Fatal编程技术网

Python 如何使django中的@cached_属性无效

Python 如何使django中的@cached_属性无效,python,django,django-models,django-views,Python,Django,Django Models,Django Views,我目前正在模型类上使用@cached_property,我想在保存时删除它,以便下次调用时可以重新填充它。我该怎么做? 例如: 谢谢只需将其作为文档删除即可。这将导致下次访问时重新计算 class SomeClass(object): @cached_property def expensive_property(self): return datetime.now() obj = SomeClass() print obj.expensive_proper

我目前正在模型类上使用
@cached_property
,我想在保存时删除它,以便下次调用时可以重新填充它。我该怎么做? 例如:


谢谢

只需将其作为文档删除即可。这将导致下次访问时重新计算

class SomeClass(object):

    @cached_property
    def expensive_property(self):
         return datetime.now()

obj = SomeClass()
print obj.expensive_property
print obj.expensive_property # outputs the same value as before
del obj.expensive_property
print obj.expensive_property # outputs new value
对于Python3,它与
del
的用法相同。下面是try/except块的示例

try:
    del obj.expensive_property 
except AttributeError:
    pass 

由于正在进行的开发,大量编辑。。。现在支持给定缓存的属性的多个标记

我遇到了一个类似的问题,其中我有一组相关的
cached\u属性
对象,它们都需要同时失效。我是这样解决的:

  • 扩展
    cached_属性
    以接受标记值并包含装饰器类方法:

    def __init__(self, func, *tags):
        self.func = func
        self.tags = frozenset(tags)
    
    @classmethod
    def tag(cls *tags):
        return lambda f: cls(f, *tags)
    
  • 在我的其他对象中,使用新的
    cached_属性.tag
    decorator类方法来定义标记的
    cached_属性
    方法:

    @cached_property.tag("foo_group")
    def foo(self):
        return "foo"
    
    def invalidate(self, tag):
        for key, value in self.__class__.__dict__.items():
            if isinstance(value, cached_property) and tag in value.tags:
                self.__dict__.pop(key, None)
    
  • 在使用新decorator的对象上,编写一个方法,通过遍历实例化对象类的
    \u dict\u
    使所有
    缓存的\u属性
    值和命名标记无效。这可以防止意外调用所有
    cached\u属性
    方法:

    @cached_property.tag("foo_group")
    def foo(self):
        return "foo"
    
    def invalidate(self, tag):
        for key, value in self.__class__.__dict__.items():
            if isinstance(value, cached_property) and tag in value.tags:
                self.__dict__.pop(key, None)
    

  • 现在,为了使其失效,我只调用了
    myobject.invalidate(“foo\u group”)
    我创建了一个Django模型mixin,当调用
    model.refresh\u from\u db()
    时,它会使模型上的所有
    @cached\u property
    属性失效。您也可以使用
    model.invalidate\u cached\u properties()
    使缓存属性无效


    灵感来自于的答案。

    如果您不想使用
    尝试
    除了
    ,并且写的行数更少,您可以使用:

    if (hasattr(obj, "expensive_property")):
        delattr(obj, "expensive_property")
    
    或:


    它将删除缓存的属性,下次访问时将再次计算该属性。

    注意,如果未访问/缓存该属性,这将生成AttributeError。在这种情况下,请尝试包装它,除了AttributeError.Good info@dalore;django开发人员的糟糕样板:(注意,如果您在类中无效,您将使用
    del self.\uuu dict\uuu['priced\u property']
    …除非有一种我不知道的非dunder方式。
    @cached_property
    绝对不是一个糟糕的样板!它是实例字典和描述符协议之间相互作用的简明用法。如果在调用/cached t属性之前尝试使用
    delattr
    ,这是非常有意义的当它抛出
    AttributeError
    时,这是bog标准的python行为。这非常有意义,因为
    cached_属性
    在第一次运行后会精确地将属性写入实例dict,而不是调用它自己。花点时间研究一下,你会发现它是一块甜美而经济的co金块de.Link已更改为;无法编辑。如果使用functools导入缓存属性的
    将无法工作。因此,我建议检查多个字段类型:
    如果isinstance(值,(缓存属性,django缓存属性)):
    if (hasattr(obj, "expensive_property")):
        del obj.expensive_property