![](/img/trans.png)
[英]Pythonic way of computing optional instance variables when first called
[英]Pythonic way to only do work first time a variable is called
我的 Python 類有一些變量需要在第一次調用它們時進行計算。 后續調用應該只返回預先計算的值。
我不想浪費時間做這項工作,除非用戶確實需要它們。 那么有沒有一種干凈的 Pythonic 方式來實現這個用例?
我最初的想法是第一次使用 property() 調用函數,然后覆蓋變量:
class myclass(object):
def get_age(self):
self.age = 21 # raise an AttributeError here
return self.age
age = property(get_age)
謝謝
class myclass(object):
def __init__(self):
self.__age=None
@property
def age(self):
if self.__age is None:
self.__age=21 #This can be a long computation
return self.__age
亞歷克斯提到你可以使用__getattr__
,這就是它的工作原理
class myclass(object):
def __getattr__(self, attr):
if attr=="age":
self.age=21 #This can be a long computation
return super(myclass, self).__getattribute__(attr)
__getattr__()
在對象上不存在屬性時調用,即。 第一次嘗試訪問age
。 每次之后, age
存在,所以__getattr__
不會被調用
正如您所見, property
不會讓您覆蓋它。 您需要使用稍微不同的方法,例如:
class myclass(object):
@property
def age(self):
if not hasattr(self, '_age'):
self._age = self._big_long_computation()
return self._age
還有其他方法,例如__getattr__
或自定義描述符類,但這種方法更簡單!-)
這是Python Cookbook 中針對此問題的裝飾器:
class CachedAttribute(object):
''' Computes attribute value and caches it in the instance. '''
def __init__(self, method, name=None):
# record the unbound-method and the name
self.method = method
self.name = name or method.__name__
def __get__(self, inst, cls):
if inst is None:
# instance attribute accessed on class, return self
return self
# compute, cache and return the instance's attribute value
result = self.method(inst)
setattr(inst, self.name, result)
return result
是的,您可以使用屬性,但通常也使用描述符來完成惰性求值,例如:
這個問題已經有 11 年的歷史了,python 3.8 及更高版本現在帶有cached_property ,它完美地滿足了這個目的。 該屬性將只計算一次,然后保存在內存中以供后續使用。
在這種情況下如何使用它:
class myclass(object):
@cached_property
def age(self):
return 21 #This can be a long computation
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.