У меня есть несколько функций, которые имеют некоторые общие входы:

func_1(x1, x2, x3, y1)
func_2(x1, x3, y2)
func_3(x1, x2, x3, y1, y3)

Я хочу написать код обработки ошибок ввода для всех входов (например, выдать исключение, если x1 равно None). Я нашел способ настройки функции проверки ввода как хороший вариант, когда все входы из всех функций могут быть проверены/подтверждены.

def validate_inputs(x1, x2, x3, y1, y2, y3)
    # do the all checks for x1, x2, x3, y1, y2, y3 here

И вызывается из соответствующих функций с необходимыми входными данными:

def func_1(x1, x2, x3, y1)
    validate_inputs(x1, x2, x3, y1)
    # do whatever the function is supposed to do

def func_2(x1, x3, y2)
    validate_inputs(x1, x3, y2)
    # do whatever the function is supposed to do

Вопрос. Как мне настроить validate_inputs, чтобы иметь такие "гибкие" входные данные?

1
anarz 13 Ноя 2019 в 12:47
Возможное решение с использованием необязательных аргументов?
 – 
Joseph
13 Ноя 2019 в 12:50
3
Посмотрите на *args и **kwargs
 – 
Chris_Rands
13 Ноя 2019 в 12:50
Используйте validate_inputs вместо decorator, выглядит лучше..
 – 
Aaron_ab
13 Ноя 2019 в 12:52
Пытаетесь настроить с помощью **kwargs, должны ли некоторые входные данные быть необязательными?
 – 
anarz
13 Ноя 2019 в 13:04
Почему бы вам просто не передать список аргументов args=[x1, x2] func_2(args) и не проверить список? validate_inputs(args). Это прекрасно работает, если вы собираетесь выполнять одинаковую проверку для любого значения, которое вы передаете. Если нет, это может потребовать дополнительной обработки
 – 
GRoutar
13 Ноя 2019 в 13:12

1 ответ

Проверьте это:

Во-первых, напишите несколько валидаторов:

def validate_int(i):
    if not type(i) == int:
        raise Exception(f"{i} is not a number")

//TODO complete code
def validate_something(i):
    if not ....:
       raise Exception(f"{i} is not something..")

Затем держите валидаторы в каком-нибудь словаре:

validators = {'x1': validate_int,
              'y1': validate_int,
              'y3': validate_int,
              'x2': validate_something}

Напишите декоратор для проверки аргументов:

def validate_args(func):
    def wrapper(*args, **kwargs):
        for k,v in kwargs.items():
            validators.get(k, lambda x: x)(v)
    return wrapper

Теперь вы хотите, чтобы каждый метод был проверен на перенос и вызывался с переменными ключ-значение:


@validate_args
def func1(*, x1,y1,y2):
    pass


@validate_args
def func2(*, x2,x5):
    pass

Вот и все. Просто назовите свои методы..

func1(x1=1,y1=2,y2=3,y3=4)

func2(x1=5, y3={'a':3})
1
Aaron_ab 13 Ноя 2019 в 13:08