<p>这就是我使用带有<a href="https://docs.python.org/3/library/functions.html#property" rel="nofollow noreferrer">properties</a>的类的意思,只是在本例中,我使用了名为<code>lazyproperty</code>的类的自定义版本。它被认为是“懒惰”的,因为它只有在被访问时才被计算,就像一个普通的<code>property</code>,但与它们不同的是,计算出的值被有效地缓存在一种方式中,将其更改为一个实例属性,这样它就不会每次都被重新计算。你知道吗</p>
<p><strong>警告:</strong>这样做假设值无论何时计算都是相同的,并且在第一次访问之后对它所做的任何更改都将对使用它的类的同一实例的其他方法可见,即它们不会看到新重新计算的值。你知道吗</p>
<p>一旦这样做了,类中的方法就可以引用<code>self.dataset1</code>或<code>self.dataset2</code>,就好像它们是常规的实例属性一样,然后,如果是第一次,将计算与其关联的数据,否则只返回先前创建的值。您可以在生成的输出中看到这种情况(如下所示)。你知道吗</p>
<pre><code># From the book "Python Cookbook" 3rd Edition.
class lazyproperty:
def __init__(self, func):
self.func = func
def __get__(self, instance, cls):
if instance is None:
return self
else:
value = self.func(instance)
setattr(instance, self.func.__name__, value)
return value
def slow_process1():
print('slow_process1() running')
return 13
def slow_process2():
print('slow_process2() running')
return 21
class Helper:
def __init__(self):
""" Does nothing - so not really needed. """
pass
@lazyproperty
def dataset1(self):
return slow_process1()
@lazyproperty
def dataset2(self):
return slow_process2()
def process_data1(self):
print('self.dataset1:', self.dataset1) # doing stuff with dataset1
return self.dataset1 * 2
def process_data2(self):
print('self.dataset2:', self.dataset2) # doing stuff with dataset2
return self.dataset2 * 2
def process_data3(self):
print('self.dataset2:', self.dataset2) # also does stuff with dataset2
return self.dataset2 * 3
if __name__ == '__main__':
helper = Helper()
print(helper.process_data1()) # Will cause slow_process1() to be called
print(helper.process_data2()) # Will cause slow_process2() to be called
print(helper.process_data3()) # Won't call slow_process2() again
</code></pre>
<p>输出:</p>
<pre class="lang-none prettyprint-override"><code>slow_process1() running
self.dataset1: 13
26
slow_process2() running
self.dataset2: 21
42
self.dataset2: 21
63
</code></pre>