2010-08-10 140 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