Class 只有在第一次调用变量时才执行工作的Python方法
我的Python类有一些变量,需要在第一次调用它们时进行计算。后续调用只应返回预计算的值 我不想浪费时间做这项工作,除非用户确实需要它们。 那么,有没有一种干净的Pythonic方法来实现这个用例呢 我最初的想法是第一次使用property()调用函数,然后重写变量:Class 只有在第一次调用变量时才执行工作的Python方法,class,variables,python,precompute,Class,Variables,Python,Precompute,我的Python类有一些变量,需要在第一次调用它们时进行计算。后续调用只应返回预计算的值 我不想浪费时间做这项工作,除非用户确实需要它们。 那么,有没有一种干净的Pythonic方法来实现这个用例呢 我最初的想法是第一次使用property()调用函数,然后重写变量: class myclass(object): def get_age(self): self.age = 21 # raise an AttributeError here return s
class myclass(object):
def get_age(self):
self.age = 21 # raise an AttributeError here
return self.age
age = property(get_age)
谢谢
Alex提到您可以使用\uuu getattr\uuu
,这就是它的工作原理
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)
\uuuu getattr\uuuuu()
在对象上不存在属性时调用,即第一次尝试访问age
。每次之后,age
存在,因此\uuuu getattr\uuuu
不会被调用是的,您可以使用属性,尽管惰性评估通常也使用描述符完成,请参见例如:
正如您所看到的,属性不允许您重写它。您需要使用稍微不同的方法,例如:
class myclass(object):
@property
def age(self):
if not hasattr(self, '_age'):
self._age = self._big_long_computation()
return self._age
还有其他方法,例如\uuu getattr\uuu
或自定义描述符类,但这一种更简单!) 是此问题的装饰程序:
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
你是在问关于备忘录的事吗。这是非常常见的OO设计模式。如果attr不存在,则调用
返回getattr(self,attr)
将导致无限循环。使用return super(MyClass,self)。\uuu getattr\uuuu(attr)
代替。毫无疑问,如果attr=='age',getattr应该返回self.age,而不是调用super的getattr。@~unutbu,super.\uu getattr\uuu
一旦创建了self.age(MyClass().age),就会返回self.age(MyClass().age)返回AttributeError:“super”对象没有属性“getattr”。我错过了什么吗?@~unutbu,我也错过了MyClass
,而不是MyClass
。哎呀。已经修好了now@nosklo,哎呀,最近做了太多的C了--修正了,tx
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