【发布时间】:2017-02-21 11:54:47
【问题描述】:
我想使用类似于通常的 lazy property 装饰器的东西,但是由于 TensorFlow 的工作方式和我使用它的方式,我需要在 __init__ 上自动初始化所有惰性属性(TensorFlow 部分是不是问题的一部分,但请参阅here 了解我的意思)。我所说的“初始化”是指调用getattr 来运行一次属性方法并缓存结果。
以下工作已经完成:
import functools
def graph_property(getter):
property_name = getter.__name__
attribute = '_cache_' + property_name
@property
@functools.wraps(getter)
def decorated(self):
if not hasattr(self, attribute):
setattr(self, attribute, getter(self))
self._graph.append(property_name) # for illustration
print('Initializing ' + property_name)
return getattr(self, attribute)
return decorated
class Test:
def __init__(self):
self._graph = []
self.inputs # DON'T LIKE TO DO THIS
self.do_stuff # AND THIS
@graph_property
def inputs(self):
return 42.0
@graph_property
def do_stuff(self):
return self.inputs + 1.0
if __name__ == '__main__':
t = Test()
print(t._graph)
但是,最好摆脱在__init__ 中手动调用self.input 和self.do_stuff ——这很快就会变得乏味。
我正在考虑多种方法来“记住”列表中某处的 graph_propertys 属性,但我认为所有都必须失败,因为在应用装饰器时,它还不知道该类(更不用说self)。
我可以想象的一种工作方式是为返回的decorated 对象提供一些标记属性,并为Test 编写一个元类,它查看所有方法,收集带有此标记的方法,并以某种方式为它们创建一个初始化程序.我未能实现这一点,因为我对元类非常不熟悉并且property 描述符不允许我添加属性。
所描述的方法是否可行(如果可行,如何实现)?或者有没有更简单的方法(没有手动开销和同样漂亮的语法)我只是没有看到它?
【问题讨论】:
标签: python python-3.x python-decorators