2017-02-22 4 views
2

파이썬 데코레이터를 써서 함수 인자를 오버라이드하려고하는데, 실제로 inner() 함수 내부에 무엇을 넣어야할지 모르겠다. args를 수정하는 적절한 방법은 무엇입니까?파이썬 데코레이터가 함수 인자를 오버라이드

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'} 

설명 :

인수가 튜플은 이름없이 인수를 포함, 우리는 대부분의 분 (LEN (인수)에서 재정의 할 수 있습니다, LEN (override_args)) 그들의.

kwargs는 dict에 명명 된 args가 key : value 쌍으로 포함되어 있습니다. 그냥 override_kwargs를 kwargs로 업데이트하십시오.

그리고 불일치 args의 순서를 막기 위해 이름이 지정된 args "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} 
관련 문제