2017-02-28 85 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