2017-02-22 116 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}