之前已经发过单独的缓存,这也算一种模式。
from __future__ import print_function import functools class lazy_property(object): def __init__(self, function): self.function = function functools.update_wrapper(self, function) def __get__(self, obj, type_): if obj is None: return self val = self.function(obj) obj.__dict__[self.function.__name__] = val return val def lazy_property2(fn): attr = '_lazy__' + fn.__name__ @property def _lazy_property(self): if not hasattr(self, attr): setattr(self, attr, fn(self)) return getattr(self, attr) return _lazy_property class Person(object): def __init__(self, name, occupation): self.name = name self.occupation = occupation self.call_count2 = 0 @lazy_property def relatives(self): # Get all relatives, let's assume that it costs much time. relatives = "Many relatives." return relatives @lazy_property2 def parents(self): self.call_count2 += 1 return "Father and mother" def main(): Jhon = Person('Jhon', 'Coder') print(u"Name: {0} Occupation: {1}".format(Jhon.name, Jhon.occupation)) print(u"Before we access `relatives`:") print(Jhon.__dict__) print(u"Jhon's relatives: {0}".format(Jhon.relatives)) print(u"After we've accessed `relatives`:") print(Jhon.__dict__) print(Jhon.parents) print(Jhon.__dict__) print(Jhon.parents) print(Jhon.call_count2) if __name__ == '__main__': main() ### OUTPUT ### # Name: Jhon Occupation: Coder # Before we access `relatives`: # {'call_count2': 0, 'name': 'Jhon', 'occupation': 'Coder'} # Jhon's relatives: Many relatives. # After we've accessed `relatives`: # {'relatives': 'Many relatives.', 'call_count2': 0, 'name': 'Jhon', 'occupation': 'Coder'} # Father and mother # {'_lazy__parents': 'Father and mother', 'relatives': 'Many relatives.', 'call_count2': 1, 'name': 'Jhon', 'occupation': 'Coder'} # Father and mother # 1