2017-02-09 27 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