【发布时间】:2016-11-19 02:02:35
【问题描述】:
我有以下代码用于在 python 3.5 中懒惰地计算一个值。我也尝试了@cached_propertydecorator,结果相同,所以为了简单起见,我将使用它。
class Foo:
@property
def expensive_object(self):
if not hasattr(self, "_expensive_object"):
print("Lengthy initialization routine")
self._expensive_object = 2
return self._expensive_object
问题是当我将它作为参数传递给函数时它会被评估,即使它最终没有在内部使用,如下例所示:
def bar(some_parameter, another_parameter):
if some_parameter != 10:
print(some_parameter)
else:
print(another_parameter)
从下面的输出中,我们看到它只是通过传递就得到了评估,但这并不是绝对必要的,因为代码没有尝试使用它。
In [23]: foo1 = Foo()
...: bar(3, foo1.expensive_object)
Lengthy initialization routine
3
In [24]: bar(3, foo1.expensive_object)
3
在某些情况下,我的脚本可以运行而无需评估,但由于这种情况,它最终还是会这样做。
将参数分解出来也是不切实际的。我也在组合成员对象的__init__ 中使用它。
如果可能的话,我想让该属性更加懒惰,因为它应该只在实际读取时进行评估。
【问题讨论】:
-
让它变得更懒的唯一方法是让它成为
bar知道在必要时调用的函数。函数参数总是立即计算。