cached_property 和 classmethod 不能一起工作,Django

Ale*_*ich 3 django django-rest-framework

我试图在视图集中一起使用cached_propertyclassmethod装饰器,但无论它们的相互位置如何,它都不起作用。有没有机会让它一起工作或cached_property不工作classmethod?特南克斯。

    @cached_property
    @classmethod
    def get_child_extra_actions(cls):
        """
        Returns only extra actions defined in this exact viewset exclude actions defined in superclasses.
        """
        all_extra_actions = cls.get_extra_actions()
        parent_extra_actions = cls.__base__.get_extra_actions()
        child_extra_actions = set(all_extra_actions).difference(parent_extra_actions)
        return (act.__name__ for act in child_extra_actions)
Run Code Online (Sandbox Code Playgroud)

N.C*_*.C. 5

对于具有类方法用法的缓存属性,我几天前编写了该代码:

from django.utils.decorators import classproperty

class cached_classproperty(classproperty):
    def get_result_field_name(self):
        return self.fget.__name__ + "_property_result" if self.fget else None

    def __get__(self, instance, cls=None):
        result_field_name = self.get_result_field_name()

        if hasattr(cls, result_field_name):
            return getattr(cls, result_field_name)

        if not cls or not result_field_name:
            return self.fget(cls)

        setattr(cls, result_field_name, self.fget(cls))
        return getattr(cls, result_field_name)
Run Code Online (Sandbox Code Playgroud)

它将在类级别缓存结果。
用法类似于classproperty

@cached_classproperty
def some_func(cls, *args, **kwargs):
    ...
Run Code Online (Sandbox Code Playgroud)

如果您的依赖项中没有 django,那么您可能希望阻止classproperty父级使用(sources)。在这种情况下,您可以使用该装饰器:

class cached_classproperty(classproperty):
    def __init__(self, method=None):
        self.fget = method

    def get_result_field_name(self):
        return self.fget.__name__ + "_property_result" if self.fget else None

    def __get__(self, instance, cls=None):
        result_field_name = self.get_result_field_name()

        if hasattr(cls, result_field_name):
            return getattr(cls, result_field_name)

        if not cls or not result_field_name:
            return self.fget(cls)

        setattr(cls, result_field_name, self.fget(cls))
        return getattr(cls, result_field_name)

    def getter(self, method):
        self.fget = method
        return self
Run Code Online (Sandbox Code Playgroud)