我想编写懒惰和可链接的函数。什么是最好的方式。
我知道一种方法是yield
而不是return
。
我希望这些函数的延迟方式类似于sqlalchemy函数在被要求从数据库中获取数据时的延迟方式。
答案 0 :(得分:6)
生成器(具有yield
而不是return
的函数)确实可以被视为“懒惰”(并且itertools.chain
可以将它们链接到任何其他迭代器,如果这就是你的意思意为“可链接”)。
但是,如果通过“可链接”(和懒惰)你的意思是你想要调用fee().fie().fo().fum()
并且所有的“辛勤工作”只发生在fum
(这似乎更接近SQLAlchemy所做的),生成器无济于事 - 你需要的是“Promise”设计模式,其中每个函数/方法(实际完成所有工作的除外)返回一个记录所有条件,参数和约束的对象在操作上,一个勤奋的功能使用该信息最终完成工作。
举一个非常简单的例子,假设“辛勤工作”正在执行remote(host, **kwargs)
形式的RPC调用。你可以用“懒人链衣服”装扮如下:
class RPC(object):
def __init__(self, host):
self._host = host
self._kws = {}
def doit(self, **morekws):
return remote(self._host, **dict(self._kws, **morekws))
def __getattr__(self, name):
def setkw(value):
self._kws[name] = value
return self
return setkw
现在,RPC(x).foo('bar').baz('bap').doit()
调用remote(x, foo=bar, baz=bap)
(当然,您可以保存链的中间阶段,将它们作为参数传递等等,直到调用doit
)。