Как обеспечить поддержу позиционных и именованных аргументов в декораторе?
Добрый день!
Пытаюсь разобраться с работой декораторов. Хочу, чтобы была поддержка как позиционных, так и именованных аргументов, однако что-то не догоняю.
def printing(function):
def inner(how, *args):
result = function(how=how, *args)
print('result =', result)
return result
return inner
@printing
def function(how=True, *args):
if how == True:
return [arg[::-1] for arg in args]
else:
return [arg for arg in args]
function(True, 'Тест', 'Тест2', 'Тест3', 'Тест4')
function(how=True, 'Тест', 'Тест2', 'Тест3', 'Тест4')
function(how=False, 'Тест', 'Тест2', 'Тест3', 'Тест4')
Выпадает:
SyntaxError: positional argument follows keyword argument
Подскажите, как исправить. Буду благодарен за любые комментарии!
Ответы (1 шт):
Позиционные аргументы в Python всегда должны идти до именованных (ошибка буквально говорит, что у вас позиционный параметр идет после именованного, что недопустимо). Поэтому, если вы хотите использовать параметр how как именованный, передавайте его последним параметром (после *args).
При этом, если вы будете передавать его как неименованный параметр, то он будет восприниматься как часть кортежа (tuple) параметров *args, его нужно вытащить из этого кортежа и передать отдельно.
def printing(function):
def inner(*args, how=None):
if how is None:
how = args[-1]
args = args[:-1]
result = function(*args, how=how)
print('result =', result)
return result
return inner
@printing
def function(*args, how=True):
if how == True:
return [arg[::-1] for arg in args]
else:
return [arg for arg in args]
function('Тест', 'Тест2', 'Тест3', 'Тест4', True)
function('Тест', 'Тест2', 'Тест3', 'Тест4', how=True)
function('Тест', 'Тест2', 'Тест3', 'Тест4', how=False)
Вывод:
result = ['тсеТ', '2тсеТ', '3тсеТ', '4тсеТ']
result = ['тсеТ', '2тсеТ', '3тсеТ', '4тсеТ']
result = ['Тест', 'Тест2', 'Тест3', 'Тест4']