#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")
Комментариев нет:
Отправить комментарий