仅在第一次调用变量时才执行工作的 Pythonic 方式
我的 Python 类有一些变量需要在第一次调用时进行计算。后续调用应该只返回预先计算的值。
我不想浪费时间做这项工作,除非用户确实需要它们。 那么有没有一种干净的 Pythonic 方式来实现这个用例呢?
我最初的想法是第一次使用 property() 调用函数,然后覆盖变量:
class myclass(object):
def get_age(self):
self.age = 21 # raise an AttributeError here
return self.age
age = property(get_age)
谢谢
my Python class has some variables that require work to calculate the first time they are called. Subsequent calls should just return the precomputed value.
I don't want to waste time doing this work unless they are actually needed by the user.
So is there a clean Pythonic way to implement this use case?
My initial thought was to use property() to call a function the first time and then override the variable:
class myclass(object):
def get_age(self):
self.age = 21 # raise an AttributeError here
return self.age
age = property(get_age)
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Alex提到您可以使用
__getattr__
,这就是它的工作原理,当对象上不存在该属性时,即调用
__getattr__()
。第一次尝试访问age
时。此后每次,age
都存在,因此__getattr__
不会被调用Alex mentioned you can use
__getattr__
, this is how it works__getattr__()
is invoked when the attribute doesn't exist on the object, ie. the first time you try to accessage
. Every time after,age
exists so__getattr__
doesn't get called如您所见,
property
不会让您覆盖它。您需要使用稍微不同的方法,例如:还有其他方法,例如 __getattr__ 或自定义描述符类,但这个更简单!-)
property
, as you've seen, will not let you override it. You need to use a slightly different approach, such as:There are other approaches, such as
__getattr__
or a custom descriptor class, but this one is simpler!-)这里是来自 Python Cookbook 针对此问题:
Here is decorator from Python Cookbook for this problem:
这个问题已经有11年历史了,python 3.8及以上版本现在带有 cached_property,它完美地满足了这个目的。该属性将仅计算一次,然后保存在内存中以供后续使用。
以下是在这种情况下如何使用它:
This question is already 11 years old, and python 3.8 and above now come with cached_property, which perfectly serves this purpose. The property will be computed only once, then kept in memory for subsequent use.
Here is how to use it in this case:
是的,您可以使用属性,尽管惰性评估通常也可以使用描述符来完成,请参见例如:
http://blog.pythonisito.com/2008/08/lazy-descriptors.html
Yes you can use properties, though lazy evaluation is also often accomplished using descriptors, see e.g:
http://blog.pythonisito.com/2008/08/lazy-descriptors.html