Декорирование функций для проверки аргументов, но игнорирование длины и позиции аргумента - PullRequest
0 голосов
/ 20 октября 2019

Я работаю над проектом, в котором, я думаю, требуется тщательная проверка аргументов. Мой проект использует win32com.client и выдает очень неразборчивые сообщения об ошибках. Чтобы защитить пользователей моего кода от этого, я хотел бы тщательно проверить входящие данные нескольких функций, которые они будут использовать.

Чтобы начать с базового примера, я хотел бы проверить аргументы функции с помощью декораторов.

import functools

def string_validate(assignment_variables):
    def decorator(f):
        @functools.wraps(f)
        def wrap(x,input_string):
            if not isinstance(input_string,str):
                raise TypeError(f"{input_string} is invalid! {assignment_variable} must be type str!")
            return f(x,input_string)
        return wrap
    return decorator

@string_validate('input_string')
def dummy_function(x,input_string):
   return

dummy_function(5,'foo')
dummy_function(5,6)
TypeError: 6 is invalid! input_string must be type str!

Так что это работает.

Однако что, если я добавлю вторую функцию

@string_validate('input_string')
def dummy_function2(input_string):
    return

Теперь я попробую ее

dummy_function2('foo')
TypeError: wrap() missing 1 required positional argument: 'input_string'

Ok. Я понимаю. Я понимаю, почему это не работает. То, что я хочу знать, существует ли обходной путь? Прямо сейчас, я думаю, что если я сделаю для проверки input_string для dummy_function2(), то мне нужно по существу сделать string_validate2.

Мой вопрос заключается в том, есть ли способ указать, какие позиционные аргументы я хочу декоратор и использовать в качестве аргументов для wrap()?

Я прочитал несколько статей ( 1, 2 , 3 ) на декораторах для проверки аргументов, и казалось, что это путь, но если мне нужно сделать новый валидатор для каждой функции, аргументы которой неПохоже, декораторы - плохая идея.

...