2017-08-23 39 views
0

我有一個模塊,我想在幾個不同的應用程序中使用。該模塊非常簡單,並具有執行特定任務的功能:在python函數中使用可選的跟蹤變量

# Fancy module 

# Task1 
def do_task1(param1): 
    step1() 
    step2() 
    step3() 

第一個應用程序直接按原樣使用它。

對於第二個應用程序,我想傳遞跟蹤器對象,以跟蹤處理的狀態。像這樣:

# Fancy module with tracker 

# Task1 
def do_task1(param1, tracker): 
    tracker.message = 'Starting step1' 
    step1() 

    tracker.message = 'Starting step2' 
    step2() 

    tracker.message = 'Starting step3' 
    step3() 

    tracker.message = 'Processing completed' 

我不想有2個版本的相同模塊庫(有和沒有跟蹤)。我可以想到的一個辦法是使跟蹤器可選,然後使用if跟蹤是否需要。

# Fancy module with conditional tracker 

# Task1 
def do_task1(param1, tracker=None): 
    if tracker: 
    tracker.message = 'Starting step1' 
    step1() 

    if tracker: 
    tracker.message = 'Starting step2' 
    step2() 

    if tracker: 
    tracker.message = 'Starting step3' 
    step3() 

    if tracker: 
    tracker.message = 'Processing completed' 

我不是太高興做的這種方式,因爲

  • 它增添了不少附加條件和代碼(影響可讀性)
  • 必須有一個更好的辦法!

有什麼建議嗎?

回答

2

一個常見的解決方案是默認使用虛擬跟蹤器:

class DummyTracker(object): 
    # your tracker API implemented here as noop 


def do_task1(param1, tracker=None): 
    if tracker is None: 
     tracker = DummyTracker() 
    tracker.message = 'Starting step1' 
    step1() 

    tracker.message = 'Starting step2' 
    step2() 

    tracker.message = 'Starting step3' 
    step3() 

    tracker.message = 'Processing completed' 
+0

謝謝,這也是我的同事所建議的。 '如果跟蹤器的行是None:tracker = Tracker()'。你會如此友善地添加這段代碼來澄清你的答案,我很樂意將它標記爲答案? –

+0

@PlastyGrove完成。 FWIW我們在我們的旗艦項目 –

+0

中有這個非常確切的模式尼斯,謝謝!這是一個非常好的主意,只是創建一個虛擬而不是導入實際的跟蹤器對象,並使用它來實例化,非常有幫助:) –

1

創建Tracker類:

Class Tracker(object): 
    def __init__(self, param1, tracker=None): 
     self.param1 = param1 
     self.tracker = tracker 

    def do_task1(param1, tracker): 
     self.message('Starting step1') 
     step1() 

     self.message('Starting step2') 
     step2() 

     self.message('Starting step3') 
     step3() 

     self.message('Processing completed') 

    def message(self, message): 
     if self.tracker: 
      self.tracker.message = message 

tracker_1 = Tracker(3) 
tracker_2 = Tracker(3, my_tracker) 
+0

這混合了責任感,並使整體非常不靈活。糟糕的設計真的。 –

+0

感謝您的回答亞歷山大。但是'tracker'對象不是同一個模塊的一部分,所以我不能使用它。 –

+0

@PlastyGrove你應該仍然可以從其他模塊導入它。 – Alexander

1

您還可以通過跟蹤下來,並用它的功能中的任何一個內登錄:

def do_task1(param1, tracker): 
    step1(tracker) 
    step2(tracker) 
    step3(tracker) 

其中:

def step1(tracker=None): 
    if tracker: 
     tracker.message = 'Starting step1' 
    ... 
+0

感謝alfasin,但它仍然需要'if'條件。我認爲布魯諾的回答是以最優雅的方式解決問題的。 –

+0

@PlastyGrove這些答案是正交的:你可以將它們結合起來並獲得最好的結果;) – alfasin