在 python 中构造首次使用的成语
Construct on first use idiom in python
嗯,在 C++ 中,aformented idom(首次使用时构造)很常见。然而,我也喜欢在 python 中制作它,连同经常伴随它的 references/pointers。只是一个简单的例子(半伪代码):
class data:
def __init__(self, file):
self.raw_data = read_file()
#takes upto 1 minute and should only be done if necessary.
self.temperature = temp_conv() #again takes a lot of time
class interface:
def __init__(self, plot, data, display_what):
self.dat = data
self.disp = display_what
self.current_time = 0
#...
def display():
#display the correct data (raw_data) or temperature
#mainly creating a matplotlib interface
self.img = self.axes.imshow(self.displ[:,:,self.current_time],interpolation='none')
#what to display actually can be changed through callbacks
def example_callback():
self.disp = self.dat.temperature
self.img.set_data(self.displ[:,:,self.current_time])
dat = data("camera.dat")
disp = interface(dat, raw_data)
disp.display()
现在第一种方法是在开始时简单地创建所有内容,但这总共需要几分钟。将来可能会更多。
所以现在我希望做到这一点,以便在我真正获得参考时只 "calculate" 需要什么。所以不是在构造数据对象时。
现在我可以在回调函数中执行此操作,在那里测试数据是否已经计算出正确的函数,如果没有计算出它。但这感觉很烦人,也不是很好的编程礼仪(接口突然负责检查和创建数据)。
所以我想让数据 class 包含它自己。删除 self.temperature = temp_conv()
并将其替换为最初将其放置在 None
的结构,但是当您第一次尝试读取它时 它会执行 temp_conv()
脚本.
很简单,只需提供 属性 而不是属性,然后仅根据需要评估代码
一个非常简单的变体是这样的:
import time
class Deferred(object):
def __init__(self, initializer):
self._initializer = initializer
self._value = None
self._initialized = False
def __call__(self):
if not self._initialized:
self._value = self._initializer()
self._initialized = True
return self._value
class Foo(object):
def __init__(self):
self._lazy_data = Deferred(lambda: time.sleep(1.0))
@property
def lazy_data(self):
return self._lazy_data()
f = Foo()
print "a"
f.lazy_data
print "b"
f.lazy_data
print "c"
嗯,在 C++ 中,aformented idom(首次使用时构造)很常见。然而,我也喜欢在 python 中制作它,连同经常伴随它的 references/pointers。只是一个简单的例子(半伪代码):
class data:
def __init__(self, file):
self.raw_data = read_file()
#takes upto 1 minute and should only be done if necessary.
self.temperature = temp_conv() #again takes a lot of time
class interface:
def __init__(self, plot, data, display_what):
self.dat = data
self.disp = display_what
self.current_time = 0
#...
def display():
#display the correct data (raw_data) or temperature
#mainly creating a matplotlib interface
self.img = self.axes.imshow(self.displ[:,:,self.current_time],interpolation='none')
#what to display actually can be changed through callbacks
def example_callback():
self.disp = self.dat.temperature
self.img.set_data(self.displ[:,:,self.current_time])
dat = data("camera.dat")
disp = interface(dat, raw_data)
disp.display()
现在第一种方法是在开始时简单地创建所有内容,但这总共需要几分钟。将来可能会更多。
所以现在我希望做到这一点,以便在我真正获得参考时只 "calculate" 需要什么。所以不是在构造数据对象时。
现在我可以在回调函数中执行此操作,在那里测试数据是否已经计算出正确的函数,如果没有计算出它。但这感觉很烦人,也不是很好的编程礼仪(接口突然负责检查和创建数据)。
所以我想让数据 class 包含它自己。删除 self.temperature = temp_conv()
并将其替换为最初将其放置在 None
的结构,但是当您第一次尝试读取它时 它会执行 temp_conv()
脚本.
很简单,只需提供 属性 而不是属性,然后仅根据需要评估代码
一个非常简单的变体是这样的:
import time
class Deferred(object):
def __init__(self, initializer):
self._initializer = initializer
self._value = None
self._initialized = False
def __call__(self):
if not self._initialized:
self._value = self._initializer()
self._initialized = True
return self._value
class Foo(object):
def __init__(self):
self._lazy_data = Deferred(lambda: time.sleep(1.0))
@property
def lazy_data(self):
return self._lazy_data()
f = Foo()
print "a"
f.lazy_data
print "b"
f.lazy_data
print "c"