2017-02-22 132 views
2

我正在尝试写一个python修饰器来覆盖函数参数,但我真的失去了什么被放在inner()函数中。这里修改参数的正确方法是什么?Python修饰符覆盖函数参数

def override(*override_args, **override_kwargs): 
     def outer(f): 
      def inner(*args, **kwargs): 
       ... 
       ... 
      return inner 
     return outer 

    @override('Cat') 
    def my_function(animal, **kwargs): 
     print args 
     print kwargs 

    my_function('Mouse', k1='1', k2='10') 

回答

2
def override(*override_args, **override_kwargs): 
    def outer(f): 
     def inner(*args, **kwargs): 
      min_args_length = min(len(args), len(override_args)) 
      args = list(args) 
      for i in xrange(min_args_length): 
       args[i] = override_args[i] 
      kwargs.update(override_kwargs) 
      return f(*args, **kwargs) 
     return inner 
    return outer 

@override('Cat', 'male', k1='0') 
def my_function(animal, **kwargs): 
    print animal 
    print kwargs 

my_function('Mouse', k1='1', k2='10') 

输出:

Cat 
{'k2': '10', 'k1': '0'} 

解释:

ARGS是一个元组包含ARGS无名称,就可以在最分钟(LEN(参数)覆盖,LEN(override_args) )他们。

kwargs是一个dict包含名为args的键:值对。只需将更新override_kwargs更新为kwargs

我强烈建议您只覆盖命名参数“kwargs”以防止不匹配参数的顺序。

0

我简化了你的例子。试着弄清楚装饰器中哪些参数来自什么参数。

def override(dec_animal): 
    def outer(func): 
     def inner(animal_to_be_ignored, **kwargs): 
      # print animal_to_be_ignored ==> This is mouse 
      return func(dec_animal, **kwargs) 
     return inner 
    return outer 


@override('Cat') 
def my_function(animal, **kwargs): 
    print animal 
    print kwargs 


my_function('Mouse', k1='1', k2='10') 

输出:

Cat {'k2': '10', 'k1': '1'}

0
class override_func_params(object): 
    def __init__(self, *args, **kwargs): 
     self.override_args = args 
     self.override_kwargs = kwargs 

    def __call__(self, func): 
     def wrapper(*args, **kwargs): 
      if kwargs: 
       kwargs.update(self.override_kwargs) 
      if args: 
       args = list(args) 
       for index, value in enumerate(self.override_args): 
        try: 
         args[index] = value 
        except IndexError: 
         break 
       args = tuple(args) 
      return func(*args, **kwargs) 
     return wrapper 


@override_func_params('a', k=1) 
def foo(*args, **kwargs): 
    print args, kwargs 

呼叫没有参数。

>>> foo() 
>>>(), {} 

调用参数,参数被覆盖。

>>> foo('b', k=2) 
>>> ('a',), {'k': 1}