2010-08-10 63 views
2

我的问题是如何设计的代码,面向对象的设计和异步deferreds作品(而不是阻塞代码)以及Python的面向对象设计defereds

好两种方式我想设计类(是这些好的设计的还是我忘了什么东西)

第一种方式

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 
+2

@ Zimm3er:我不太确定你在问什么。你能否纠正代码的格式,并且包括可执行的代码和/或描述你的设计困境?代码的目的不明确时,我很难去考虑设计。 – MattH 2010-08-10 09:15:46

回答

1

短答案:参见@defer.inlineCallbacks

不管功能或面向对象的编程使用扭曲的症结和福是,它使用一个回调事件驱动设计,以允许异步程序的执行。一个常见的观察是事件驱动的编程需要改变编码风格和布局 - 正如你的问题所表明的那样。

在几乎所有情况下,在您的方法或函数中使用“@ defer.inlineCallbacks”装饰器将有助于使您的代码变得模块化并且可重用。当你使用这种方法编写源代码时,你可以编写不在许多函数之间“分离”的异步代码。每次您的代码块需要进入下一个阻塞或“延迟”的段时,它都使用yield命令。这允许函数在延迟结束时继续离开它的位置。这使得回调链看起来像普通的阻止代码。

More Help