Страницы

Поиск по вопросам

вторник, 10 декабря 2019 г.

Кто в Python должен проверять, правильного ли типа аргументы передаются в функцию или метод?

#python


Кто в Python должен проверять, правильного ли типа аргументы передаются в функцию
или метод: 


Программист вызывающий функцию обязан обеспечить правильность типа передаваемого
аргумента. Функция не проверяет явно на первых этапах переданный аргумент, а просто
использует его как будто он достоверно правильного типа. В процессе работы функции
могут самостоятельно сгенерироваться или быть сгенерированы явно различные исключения,
которые будут свидетельствовать о неправильном аргументе. Эту исключения будут описаны
в docstring
Функция явно на первом этапе проверяет тип переданного аргумента и генерирует исключение
если что-то нет так, например, TypeError.
Что-то иное


?

Например, если в функцию (для примера)  мы передадим не iterable, а целое или вещественное
число, то сгенерируется исключение TypeError (т.к. int и float не iterable). Но можно
же в самом начале самому явно проверить, например, что переданный аргумент является
итерируемым объектом и что-то сгенерировать.


def is_positive_or_zero_values(iterable):
    """Проверить все ли элементы в iterable есть числа равные или больше нуля.

    Args:
        iterable: итерируемый объект, содержащий значения на проверку.
    Returns:
        bool: True, если все элементы в iterable есть числа, которые равные или больше
нуля..
              False, иначе.
    """
    if iterable:
        if is_numbers(iterable):
            return all(map(lambda x: x >= 0, iterable))
        else:
            return False
    else:
        return False

    


Ответы

Ответ 1



Эта тема поднималась и в Python in Nutshell, и в Fluent Python. Pythonic way - вообще не проверять аргументы. Цитата из Glossary: Pythonic programming style that determines an object's type by inspection of its method or attribute signature rather than by explicit relationship to some type object ("If it looks like a duck and quacks like a duck, it must be a duck.") By emphasizing interfaces rather than specific types, well-designed code improves its flexibility by allowing polymorphic substitution. Duck-typing avoids tests using type() or isinstance(). Instead, it typically employs the EAFP (Easier to Ask Forgiveness than Permission) style of programming.

Ответ 2



from functools import wraps import inspect def checker(fn): @wraps(fn) def wrapper(*args, **kwargs): insp = inspect.getfullargspec(fn) for name, _type in insp.annotations.items(): arg = args[insp.args.index(name)] msg = '%s=%s' % (name, arg), '%s - %s' % (_type, _type == type(arg)) print(msg) if not isinstance(arg, _type): raise UserWarning(msg) return fn(*args, **kwargs) return wrapper @checker def testFn(dt: dict, num: int, st: str): print('OK\n') testFn({'key': True}, 1, 'asd') testFn({'key': None}, 2, 77) out: ('num=1', " - True") ('st=asd', " - True") ("dt={'key': True}", " - True") OK ('num=2', " - True") ('st=77', " - False") Traceback (most recent call last): File "C:/Scripts/python/2016/3/213123.py", line 22, in testFn({'key': None}, 2, 77) File "C:/Scripts/python/2016/3/213123.py", line 13, in wrapper raise UserWarning(msg) UserWarning: ('st=77', " - False")

Комментариев нет:

Отправить комментарий