Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Class 只有在第一次调用变量时才执行工作的Python方法_Class_Variables_Python_Precompute - Fatal编程技术网

Class 只有在第一次调用变量时才执行工作的Python方法

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

我的Python类有一些变量,需要在第一次调用它们时进行计算。后续调用只应返回预计算的值

我不想浪费时间做这项工作,除非用户确实需要它们。 那么,有没有一种干净的Pythonic方法来实现这个用例呢

我最初的想法是第一次使用property()调用函数,然后重写变量:

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