Reputation: 27189
I like the cached_property
module: https://pypi.python.org/pypi/cached-property
Is there a way to get cached properties for classes?
Here is an example for "properties for classes"
class Foo(object):
@classmethod
def get_bar(cls):
return 'bar'
@cached_class_property
def bar(cls):
return 'bar'
Usage:
assert Foo.bar == Foo.get_bar()
With "cached" I mean that the second (and later) calls to the property returns the value of the first call.
Upvotes: 0
Views: 403
Reputation: 251196
Properties are nothing but descriptors, and when we define a descriptor it is always looked up on the type of the object. For instances a descriptor will be looked up on its class and similarly for a class it is going to be looked up on its type, i.e Metaclass.
import random
class cached_class_property(object):
def __init__(self, func):
self.func = func
self.name = '_' + func.__name__
def __get__(self, obj, type):
if obj is None:
return self
sentinel = object()
value = getattr(obj, self.name, sentinel)
if value is sentinel:
value = self.func(obj)
setattr(obj, self.name, value)
return value
class Meta(type):
@cached_class_property
def bar(cls):
value = random.random()
return value
class Foo(object):
__metaclass__ = Meta
Demo:
>>> %run so.py
>>> Foo.bar
0.3896508798298206
>>> Foo.bar
0.3896508798298206
>>> Foo.bar
0.3896508798298206
>>> class Bar(Foo):
... pass
...
>>> Bar.bar
0.3896508798298206
>>> Bar.bar
0.3896508798298206
Upvotes: 1