ज़रूर, सिर्फ अपनी संपत्ति की स्थापना की है एक उदाहरण विशेषता है कि बाद के उपयोग पर दिया जाता है:
class Foo(object):
_cached_bar = None
@property
def bar(self):
if not self._cached_bar:
self._cached_bar = self._get_expensive_bar_expression()
return self._cached_bar
property
वर्णनकर्ता एक डेटा डिस्क्रिप्टर है (यह __get__
, __set__
और __delete__
डिस्क्रिप्टर हुक लागू करता है), इसलिए यह उदाहरण दिया जाएगा कि bar
विशेषता उदाहरण पर मौजूद है, अंत परिणाम के साथ कि पाइथन उस विशेषता को अनदेखा करता है, इसलिए अलग से परीक्षण करने की आवश्यकता attrib प्रत्येक पहुंच पर ute। यदि आप एक __getattr__
दृष्टिकोण पसंद करते हैं
class CachedProperty(object):
def __init__(self, func, name=None):
self.func = func
self.name = name if name is not None else func.__name__
self.__doc__ = func.__doc__
def __get__(self, instance, class_):
if instance is None:
return self
res = self.func(instance)
setattr(instance, self.name, res)
return res
class Foo(object):
@CachedProperty
def bar(self):
return self._get_expensive_bar_expression()
(जो कुछ करना है:
आप यदि वह मौजूद है अपनी खुद की जानकारी, जिसका केवल लागू करता __get__
है, जो बिंदु पर पायथन वर्णनकर्ता से अधिक उदाहरण पर एक विशेषता का उपयोग करता है लिख सकते हैं इसके लिए कहते हैं), कि हो जाएगा:
class Foo(object):
def __getattr__(self, name):
if name == 'bar':
bar = self.bar = self._get_expensive_bar_expression()
return bar
return super(Foo, self).__getattr__(name)
बाद पहुँच उदाहरण पर bar
विशेषता मिलेगा और __getattr__
परामर्श नहीं किया जाएगा।
डेमो:
>>> class FooExpensive(object):
... def _get_expensive_bar_expression(self):
... print 'Doing something expensive'
... return 'Spam ham & eggs'
...
>>> class FooProperty(FooExpensive):
... _cached_bar = None
... @property
... def bar(self):
... if not self._cached_bar:
... self._cached_bar = self._get_expensive_bar_expression()
... return self._cached_bar
...
>>> f = FooProperty()
>>> f.bar
Doing something expensive
'Spam ham & eggs'
>>> f.bar
'Spam ham & eggs'
>>> vars(f)
{'_cached_bar': 'Spam ham & eggs'}
>>> class FooDescriptor(FooExpensive):
... bar = CachedProperty(FooExpensive._get_expensive_bar_expression, 'bar')
...
>>> f = FooDescriptor()
>>> f.bar
Doing something expensive
'Spam ham & eggs'
>>> f.bar
'Spam ham & eggs'
>>> vars(f)
{'bar': 'Spam ham & eggs'}
>>> class FooGetAttr(FooExpensive):
... def __getattr__(self, name):
... if name == 'bar':
... bar = self.bar = self._get_expensive_bar_expression()
... return bar
... return super(Foo, self).__getatt__(name)
...
>>> f = FooGetAttr()
>>> f.bar
Doing something expensive
'Spam ham & eggs'
>>> f.bar
'Spam ham & eggs'
>>> vars(f)
{'bar': 'Spam ham & eggs'}
आप वर्णनकर्ता के साथ स्वचालित रूप से ऐसा कर सकते हैं: http://jeetworks.org/node/62 – schlamar
WERKZEUG व्यापक साथ एक बेहतर कार्यान्वयन है टिप्पणियां: https://github.com/mitsuhiko/werkzeug/blob/10b4b8b6918a83712170fdaabd3ec61cf07f23ff/werkzeug/utils.py#L35 – schlamar
यह भी देखें: [पायथन आलसी संपत्ति सजावट] (http://stackoverflow.com/questions/3012421/python- आलसी-संपत्ति-डेकोरेटर)। – detly