我目前正在阅读Stanford lecture给出的tensorflow教程。它正在教授关于概念调用"延迟加载"。在幻灯片中,它解释了我们可以通过利用python的属性来避免这种情况。
我对Python比较陌生,他正在谈论的属性究竟是什么?
使用Python属性确保函数在第一次调用时加载*
答案 0 :(得分:1)
对于使用 @property 装饰器进行延迟评估here的描述非常好。基本上, @property 装饰器允许您定义一个实例变量:
要看到这一点,请考虑代码(注意,此代码是从上一个链接中获取和更改的,因此应该归功于Steven Loria):
class Node_normal:
def __init__(self):
print("nn")
self.val = 2
class Node_lazy:
def val(self):
print("nl")
return 2
class Node_property:
def __init__(self):
self._val = False
@property
def val(self):
if not self._val:
print("np")
self._val = 2
return self._val
当实例化Node_normal对象时,将初始化self.val并立即为其分配值2(正常加载),而Node_lazy将被实例化但不分配值。相反,它在调用val()时延迟返回值(延迟加载)。最后,当实例化Node_property时,将使用默认值(False)初始化self._val,并在调用时分配true值(2)并将其存储在self._val中,以便在进一步调用时再次引用。
你可以用以下方法测试:
exec(open("node_normal.py").read())
exec(open("node_lazy.py").read())
exec(open("node_property.py").read())
class Graph:
def __init__(self):
nn = Node_normal()
self.nodes1 = [nn.val for x in range(1,10)]
nl = Node_lazy()
self.nodes2 = [nl.val() for x in range(1,10)]
np = Node_property()
self.nodes3 = [np.val for x in range(1,10)]
g = Graph()
print(g.nodes1)
print(g.nodes2)
print(g.nodes3)
给出了结果
nn
nl
nl
nl
nl
nl
nl
nl
nl
nl
np
[2, 2, 2, 2, 2, 2, 2, 2, 2]
[2, 2, 2, 2, 2, 2, 2, 2, 2]
[2, 2, 2, 2, 2, 2, 2, 2, 2]
请注意,g.nodes中的值对于所有三种方式都是相同的,但Node_normal和Node_property只需要运行一次赋值,而Node_lazy只需要进行10次赋值。另外,在调用np.val之前,Node_property没有为self._val分配2。当分配值是一个昂贵的调用时(这不是这种情况),这是最有用的。
还有其他原因使用 @property 装饰器,see here。
答案 1 :(得分:0)
如果您查看相关的讲义,它会为此提供链接: http://danijar.com/structuring-your-tensorflow-models/。