如何创建装饰器以延迟初始化属性
我想创建一个像属性一样工作的装饰器,只是它仅调用装饰函数一次,并且在后续调用中始终返回第一次调用的结果。一个例子:
def SomeClass(object):
@LazilyInitializedProperty
def foo(self):
print "Now initializing"
return 5
>>> x = SomeClass()
>>> x.foo
Now initializing
5
>>> x.foo
5
我的想法是为此编写一个自定义装饰器。所以我开始了,这就是我的进展:
class LazilyInitializedProperty(object):
def __init__(self, function):
self._function = function
def __set__(self, obj, value):
raise AttributeError("This property is read-only")
def __get__(self, obj, type):
# problem: where to store the value once we have calculated it?
如您所见,我不知道在哪里存储缓存的值。最简单的解决方案似乎是只维护一本字典,但我想知道是否有更优雅的解决方案。
编辑抱歉,我忘了提及我希望该属性是只读的。
I want to create a decorator that works like a property, only it calls the decorated function only once, and on subsequent calls always return the result of the first call. An example:
def SomeClass(object):
@LazilyInitializedProperty
def foo(self):
print "Now initializing"
return 5
>>> x = SomeClass()
>>> x.foo
Now initializing
5
>>> x.foo
5
My idea was to write a custom decorator for this. So i started, and this is how far I came:
class LazilyInitializedProperty(object):
def __init__(self, function):
self._function = function
def __set__(self, obj, value):
raise AttributeError("This property is read-only")
def __get__(self, obj, type):
# problem: where to store the value once we have calculated it?
As you can see, I do not know where to store the cached value. The simplest solution seems to be to just maintain a dictionary, but I am wondering if there is a more elegant solution for this.
EDIT Sorry for that, I forgot to mention that I want the property to be read-only.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Denis Otkidach 的 CachedAttribute 是一个方法装饰器,它使得惰性属性(计算一次,可访问多次)。为了使其只读,我添加了一个
__set__
方法。为了保留重新计算的能力(见下文),我添加了一个__delete__
方法:例如:
CachedAttribute
的美妙之处之一(以及ReadOnlyCachedAttribute) 是如果你
del foo.bar
,那么下次你访问
foo.bar
,该值被重新计算。 (这个魔法是通过事实上,
del foo.bar
从foo.__dict__
中删除了'bar'
,但属性bar
保留在Foo.__dict__
中。)如果您不需要或不希望重新计算此功能,
那么以下(基于Mike Boers的lazyprop)是一种更简单的方法创建一个只读的惰性属性。
Denis Otkidach's CachedAttribute is a method decorator which makes attributes lazy (computed once, accessible many). To make it also read-only, I added a
__set__
method. To retain the ability to recalculate (see below) I added a__delete__
method:For example:
One of the beautiful things about
CachedAttribute
(andReadOnlyCachedAttribute) is that if you
del foo.bar
, then the next time youaccess
foo.bar
, the value is re-calculated. (This magic is made possible bythe fact that
del foo.bar
removes'bar'
fromfoo.__dict__
but the propertybar
remains inFoo.__dict__
.)If you don't need or don't want this ability to recalculate,
then the following (based on Mike Boers' lazyprop) is a simpler way to make a read-only lazy property.