2017-02-28 87 views
0

處理庫的新版本我更改了幾個函數的默認參數之一。所以我想添加一個臨時警告,當用戶調用一個沒有顯式指定參數的函數時(所以函數被調用它的默認值)。修飾器,改變函數的某些參數

它可能只是通過添加預警功能,把它裏面的每個基函數很容易做到:

def warning(formatting): 
    if formatting is None: 
     sys.stderr.write("WARNING: The default format has changed to new_format") 
     return 'new_format' 
    return formatting 

def my_function(arg1, arg2, formatting=None): 
    formatting = warning(formatting) 
    ... # the following function code 

但是它會更方便使用裝飾(代碼可讀性)做到這一點。所以,我實現了這樣的事情:

def check_default_format(fun): 
    def warning(*a, **kw): 
     if 'formatting' not in kw.keys() or kw['formatting'] is None: 
      kw['formatting'] = 'new_format' 
      sys.stderr.write("WARNING: The default format has changed to new_format") 
     return fun(*a, **kw) 
    return warning 

@check_default_format 
def my_function(arg1, arg2, formatting=None): 
    ... # the function code 

那當我打電話my_functionformatting參數,如果formatting被指定爲關鍵字參數按預期工作。 但如何包含my_function只能使用位置參數調用的可能性?由於重複formatting參數,調用裝飾my_function('arg1', 'arg2', 'some_format')將產生TypeError

注:我不能認爲formatting總是第三個參數,因爲我需要裝飾不同的功能。我也無法更改參數順序以保持向後兼容性。

+0

將'formatting'的默認值總是'None'? –

+0

有效的默認格式是(總是)'new_format'。在函數聲明中,它總是(也總是)設置爲None,以允許我們確定用戶是隱式指定了'new_format'還是用默認值調用函數。 – Dado

回答

1

在Python 3,你可以使用檢查模塊的Signature.bind_partial

def check_default_format(fun): 
    @wraps(fun) 
    def wrapper(*a, **kw): 
     sig= inspect.signature(fun) 
     args= sig.bind_partial(*a, **kw) 

     if 'formatting' not in args.arguments or args.arguments['formatting'] is None: 
      kw['formatting'] = 'new_format' 
      sys.stderr.write("WARNING: The default format has changed to new_format") 
     return fun(*a, **kw) 
    return wrapper