Pregunta

mi clase Python tiene algunas variables que requieren trabajo para calcular la primera vez que se llaman. Las llamadas posteriores sólo debe devolver el valor previamente calculado.

No quiero perder el tiempo haciendo este trabajo a menos que sean realmente necesarios por parte del usuario. Entonces, ¿hay una manera Pythonic limpia para poner en práctica este caso de uso?

Mi idea inicial era utilizar la propiedad () para llamar a una función del primer tiempo y luego anular la variable:

class myclass(object):
    def get_age(self):
        self.age = 21 # raise an AttributeError here
        return self.age

    age = property(get_age)

Gracias

¿Fue útil?

Solución

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

Alex mencionó que puede utilizar __getattr__, así es como funciona

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__() se invoca cuando el atributo no existe en el objeto, es decir. la primera vez que intente acceder age. Cada vez después, existe por lo age __getattr__ no consigue llamado

Otros consejos

property, como hemos visto, no deje que lo sustituya. Es necesario utilizar un enfoque ligeramente diferente, como por ejemplo:

class myclass(object):

    @property
    def age(self):
      if not hasattr(self, '_age'):
        self._age = self._big_long_computation()
      return self._age

Hay otros enfoques, tales como __getattr__ o una clase de descriptor de costumbre, pero éste es más simple -)

Aquí es decorador de Python Cookbook para este problema:

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

Si usted puede utilizar las propiedades, aunque la evaluación perezosa también a menudo se lleva a cabo usando descriptores, véase, por ejemplo:

http://blog.pythonisito.com/2008/08/lazy -descriptors.html

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top