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 __ ()
вызывается, когда атрибут не существует в объекте, т.е. при первой попытке доступа к возрасту
. Каждый раз после этого существует возраст
, поэтому __ 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
свойство
, как вы видели, не позволит вам переопределить это. Вам нужно использовать немного другой подход, например:
class myclass(object):
@property
def age(self):
if not hasattr(self, '_age'):
self._age = self._big_long_computation()
return self._age
Есть и другие подходы, такие как __ getattr __
или собственный класс дескриптора, но этот проще! -)
Да, вы можете использовать свойства, хотя ленивое вычисление также часто выполняется с использованием дескрипторов, см. Например: