2017-02-09 33 views
1

我有一類項目的以下兩個功能:分解出使用Python裝飾共享數據驗證

def stage_changes(self, change_set_name): 
    change_set_id = self._get_change_set_id(change_set_name) 
    # Perform validation on change set ID 
    self._stage_changes_internal(change_set_id) 

def commit_changes(self, change_set_name): 
    change_set_id = self._get_change_set_id(change_set_name) 
    # Perform validation on change set ID (same validation as first function) 
    # Perform some other computation using change set ID 
    self._commit_changes_internal(change_set_id, ...) 

我找前兩個共享線路分解出的這些功能,即

change_set_id = self._get_change_set_id(change_set_name) 
# Perform validation on change set ID 

我的問題:

  1. 是否使用裝飾實際意義在這裏,還是我想太CREA在我應該只是調用一個簡單的幫助函數的地方tive?
  2. 如果沒有有意義使用的裝飾,我將如何去構建它?它好像它可能是很麻煩的話,因爲我需要在公共尾聲計算出的值中的每個函數執行額外的計算(即共享的邏輯不僅僅能產生副作用,它返回一個值) 。

回答

0

正如你所說,你可以使用一個輔助函數應用DRY原則。 我認爲它更多的個人品味,這裏使用輔助或裝飾功能。 但作爲裝飾,它看起來是這樣的:

from functools import wraps 

def validateData(fn): 
    @wraps(fn) 
    def wrapper(*args, **kw): 
     cls = args[0] 
     change_set_name = args[1] 

     if change_set_name in ('bar', 'foobar'): 
      kw['change_set_id'] = 1 
     else: 
      kw['change_set_id'] = None 

     return fn(*args, **kw) 
    return wrapper 


class Foo(): 
    @validateData 
    def stage_changes(self, change_set_name, change_set_id=None): 
     print('change_set_id in stage_changes:', change_set_id) 
     # Perform validation on change set ID 
     #self._stage_changes_internal(change_set_id) 

    @validateData 
    def commit_changes(self, change_set_name, change_set_id=None): 
     #change_set_id = self._get_change_set_id(change_set_name) 
     print('change_set_id in commit_changes:', change_set_id) 
     # Perform validation on change set ID (same validation as first function) 
     # Perform some other computation using change set ID 
     #self._commit_changes_internal(change_set_id, ...) 

f = Foo() 
f.stage_changes('bar') 
f.stage_changes('banana') 

打印:

change_set_id in stage_changes: 1 
change_set_id in stage_changes: None