从装饰器检查并实时修改调用参数

时间:2015-10-07 13:28:59

标签: python python-2.7

我的用例如下:

@AddOne("b")
def func(a, b, c, *args, **kwargs):
    print a, b, c

预期行为:

>>> func(1, 2, 3)
1 3 3
>>> func(a=1, c=3, b=2)
1 3 3

我怀疑我必须使用inspect模块使用getcallargsgetargspec之类的代码对装饰器进行编码,但我无法以编程方式执行它。我错过了什么吗?

编辑:我的尝试是以下内容:

class AddOne(object):
    def __init__(self, param_name):
        self.param_name = param_name

    def __call__(self, func):
        @wraps(func)
        def decorated(*args, **kwargs):
            new_args = list(args)
            new_kwargs = kwargs

            v = extract_parameter_somehow(
                func, new_args, kwargs, 
                self.param_name) + 1

            kwargs[self.param_name] = v
            return func(*new_args, **kwargs)
        return decorated

2 个答案:

答案 0 :(得分:0)

选项(可能有点hackish?)是使用 var nameObj=function(){ var _locname; return { item:'item1', getNameObj: function(){ return _locname }, setNameObj: function(nm){ _locname = nm } } }(); console.log(nameObj.setNameObj('tempValue')); console.log(nameObj.getNameObj());然后对getargspecargs进行破坏性查找

kwargs

答案 1 :(得分:0)

模块inspect包含满足您要求所需的一切:

  • getargspec为您提供了解参数及其顺序的确切定义
  • getcallargs处理实际参数并提供其值

代码可以是:

 class AddOne(object):
    def __init__(self, param_name):
        self.param_name = param_name

    def __call__(self, func):
        self.argspec = inspect.getargspec(func)
        @wraps(func)
        def decorated(*args, **kwargs):
            callargs = inspect.getcallargs(func, *args, **kwargs)
            if callargs.has_key(self.param_name):
        callargs[self.param_name] += 1
        elif callargs[self.argspec.keywords].has_key(self.param_name):
        callargs[self.argspec.keywords][self.param_name] += 1
            new_args = [ callargs[i] for i in self.argspec.args
             ] + list(callargs[self.argspec.varargs])
            new_kwargs = callargs[self.argspec.keywords]
            return func(*new_args, **kwargs)
        return decorated

这意味着:

  • 使用getcallargs处理作为键控参数给出的默认值和位置参数
  • 在位置参数中搜索param_name - 如果找到则增加相应的值
  • 如果在位置参数中找不到,则在关键字参数中搜索 - 如果找到则增加相应的值

然后,位置参数列表和关键字的哈希是根据getcallargs返回的值构建的,以允许额外的变量或其他关键字参数。