2017-02-21 42 views
0

Я пишу декоратор, который поймает TypeError для неправильного количества аргументов в вызове функции и распечатает настроенное сообщение. Код здесь:Сохранять подпись в Decorator python 2

import inspect 

def inspect_signature(f): 
    def decorate(*args, **kwargs): 
     try: 
      f(*args, **kwargs) 
     except TypeError as e: 
      print('Failed to call "{}" with signature {}. Provided args={} and kwargs={}.'.format(
       f.__name__, inspect.getargspec(f).args, args, kwargs)) 
     return f 
    return decorate 


@inspect_signature 
def func(foo, bar): 
    pass 
func('a') 
func('a', 'b') 

я получаю следующий результат:

Failed to call "func" with signature ['foo', 'bar']. Provided args=('a',) and kwargs={}. 
Called successfully with foo=a, bar=b 
ArgSpec(args=[], varargs='args', keywords='kwargs', defaults=None) 

Функция подписи пуста. Пожалуйста, предложите мне решение, как я могу его сохранить?

PS: Я использую python2 и не могу переключиться на python3.

+0

Я обновил ответ. Вы получили это? –

ответ

0

Вы пропустили это здесь. func (* foo, ** bar)

В вашем случае func('a') не работал, так как вы дали фиксированный аргумент для этого.

Вы должны передать переменное количество аргументов вашей функции

@inspect_signature 
def func(*foo, **bar): 
    pass 
+0

Я не передаю переменную количество аргументов функции. Я установил два аргумента. Я знаю, что 'func ('a')' не будет работать так, потому что я написал декоратор, который напечатает настроенное сообщение вместо встроенного сообщения об ошибке python, но моя оригинальная сигнатура функции будет потеряна. Поэтому я хочу сохранить его. –

+0

@python_user Итак, каково было определение для вашей оригинальной функции подписи? –

0

Вы можете обратиться к Preserving signatures of decorated functions.

Одним словом, вы можете использовать decorator модуль в Python2 и Python3. Когда вы используете Python3.4 +, вы можете использовать inspect.wraps для сохранения подписи украшенных функций.

Если вы не хотите использовать модуль decorator, вы можете использовать eval, чтобы сделать декоратор. В общем, eval непопулярен, поэтому модуль decorator может быть лучшим решением в Python2.