我的问题是如何设计与面向对象设计和异步延迟(而不是阻塞代码)很好地协同工作的代码。
好的,我在考虑设计这个类的两种方式(这些是好的设计,还是我忘了什么)
第一种方法
class Grooveshark(object):
def get_session(self):
d = # implementation detail (gets page)
d.addCallback(self.parse_session)# implmentation detail
# all in all this goes through and sets self.session to the session value (it does not return it though; should I set it and return it?)
self.session_time = time.time()
return d
def get_country_id(self):
# implmentation acts same as d just parses to diferrent id
# also it grabs the same page; ANNOYING having to get the page twice ugh
def get_token(self):
# relies on self.session being set
d = # implmentation detail
d.addCallback(self.parse_token)# implmentation detail
# at the end of the day it sets self.token and then fires the deferred (same as session does not send it through the deferred, again should I seem repetitive?)
return d
def construct_api_call(method, url, implmentation_arguments...)
# checks if session is hour old
if self.session_time - 3600 <= time.time() or self.session is None:
# update
d = get_session()
# some how pass deferred or something
d.addCallback(lambda ignored: self.get_country_id)
d.addCallback(lambda ignored: self.get_token())
d.addCallback(lambda ignored: self.construct_api_call(method, url, implmentation_arguments)
# if error retry
d.addErrback(lambda error: log.err(error))
d.addErrback(lambda ignored: self.construct_api_call(method, url, implmentation_arguments)
return d# would this work? problem: with this how do I get it so I can do this whole update and do this again with the deferred I returned
else:
#implmentation details
return d# fires when done with api call第二种方式
class Grooveshark(object):
def get_session(self):
d = # implmentation detail
# differance this sends the session down the deferred callback and sets the instance var self.session (seems strange both modifying state and returning)
def get_token(self, session):
d = # gets token but uses session argument NOT intance variable
def get_country_id # same as first class
def construct_api_call(session, session_time, token, country_id, all the other args in above class):
# problems it requires user of api to store session etc also how do I return if needs update right now I just error
if self.session_time - 3600 <= time.time():
raise RuntimeError("You need to update your session, ugh why does the user have to store the session ugh")
else:
# does what above class does as well发布于 2011-02-04 07:29:50
简短的回答:请参阅@defer.inlineCallbacks
不管是函数式编程还是面向对象编程,使用Twisted的关键和好处在于,它使用回调事件驱动设计来允许异步程序执行。一个常见的观察是,事件驱动编程需要改变编码风格和布局-正如您的问题所指出的那样。
在几乎所有情况下,在方法或函数中使用"@defer.inlineCallbacks“修饰器将有助于使扭曲的代码模块化和可重用。当您使用这种方法编写源代码时,您可以编写不会在这么多函数之间“分割”的异步代码。每当你的代码块需要转到下一个阻塞或“延迟”段时,它都会使用yield命令。这允许函数在延迟完成时从它停止的地方继续。这使得回调链看起来像是常规的阻塞代码。
More Help
https://stackoverflow.com/questions/3445668
复制相似问题