2015-12-21 2 views
3

Я пытаюсь написать декоратор, который будет делать некоторые действия на основе kwargs, пока я хочу сохранить подпись функций одновременно.Как разрешить параметры для декоратора, одновременно сохраняя подпись функции?

Вот тест блок я хочу передать:

def test_test_deprecator(self): 

    @test_deprecator("here is decorator message", 'z'): 
    def some_method(x, y, z): 
     return x + y 

    self.assertEqual(some_method(2, 2, z=6), 4) 

    # test the original function's signature 
    argspec = inspect.getargspec(some_method) 
    self.assertEqual(argspec.args, ["x", "y", "z"]) 

я написал что-то вроде:

import decorator 

def test_decorator(message, args_name): 

    @decorator.decorator 
    def _test_docorator(f, *args, **kwargs): 
     if args_name in kwargs: 
      print(message) 
     return f(*args, **kwargs) 

    return _test_docorator 

Испытательное устройство может пройти, но не выдает сообщение, потому что kwargs всегда пустой.

Кто-нибудь знает, как этого достичь?

ответ

1

Я не уверен, что роль @decorator.decorator в вашем коде, но здесь декоратор делать то, что вы описали:

def test_decorator(message, arg_name): 
    def _test_decorator(f): 
     def wrapped_f(*args, **kwargs): 
      if arg_name in kwargs: 
       print(message) 
      return f(*args, **kwargs) 
     return wrapped_f 
    return _test_decorator 

Обновленный ответ:

я узнал немного о декораторы, изучающие это. Короче говоря, хотя, я думаю, используя wrapt модуль будет работать для вас: код

def test_decorator(message, arg_name): 
    @wrapt.decorator 
    def wrapped_f(f, instance, args, kwargs): 
     if arg_name in kwargs: 
      print(message) 
     return f(*args, **kwargs) 
    return wrapped_f 

Тест:

@test_decorator('found it', 'y') 
def foo(x="bad", y="dog"): 
    print("x={}, y={}".format(x, y)) 

def bar(x="bad", y="dog"): 
    print("x={}, y={}".format(x, y)) 

print ("foo argspec={}".format(inspect.getargspec(foo))) 
print ("bar argspec={}".format(inspect.getargspec(bar))) 

foo(y='cat') 

Выход:

foo argspec=ArgSpec(args=['x', 'y'], varargs=None, keywords=None, defaults=('bad', 'dog')) 
bar argspec=ArgSpec(args=['x', 'y'], varargs=None, keywords=None, defaults=('bad', 'dog')) 
found it 
x=bad, y=cat 
+0

Я хочу, чтобы сохранить функцию подписи , что означает, что когда я использую «argspec = inspect.getargspec (fn)», он получает аргументы для fn. –

+0

Извините, я лучше понимаю, как некоторые детали вокруг декораторов, так и то, что вы спрашивали сейчас. Я обновил свой ответ. – Turn

+0

Нет, это не работает. с @ wrapt.decorator, kwargs по-прежнему пуст, а args становятся dict, это даже вызывает ошибку при запуске f (* args, ** kwargs). –

Смежные вопросы