Во многих задачах требуется контроль входных данных, в частности, несмотря на динамическую типизацию, их типов.
Разработайте декоратор same_type
, который производит проверку переменного количества позиционных параметров. В случае получения не одинаковых типов выводит сообщение “Обнаружены различные типы данных” и прерывает выполнение функции.
Примечание
Ваше решение должно содержать только функции.
В решении не должно быть вызовов требуемых функций.
Пример
Ввод
@same_type
def a_plus_b(a, b):
return a + b
print(a_plus_b(3, 5.2) or 'Fail')
print(a_plus_b(7, '9') or 'Fail')
print(a_plus_b(-3, 5) or 'Fail')
Вывод
Обнаружены различные типы данных
Fail
Обнаружены различные типы данных
Fail
2
Ввод
@same_type
def combine_text(*words):
return ' '.join(words)
print(combine_text('Hello,', 'world!') or 'Fail')
print(combine_text(2, '+', 2, '=', 4) or 'Fail')
print(combine_text('Список из 30', 0, 'можно получить так', [0] * 30) or 'Fail')
Вывод
Hello, world!
Обнаружены различные типы данных
Fail
Обнаружены различные типы данных
Fail
Решение
Достаточно простая задача. Нам нужно реализовать функцию-обертку, которая перед передачей параметров проверяла бы их на однотипность. Если все параметры одинаковы, то вызывала бы функцию-содержание и возвращала результат, в противном случае возвращала бы сообщение о неоднотипности данных.
Тут следует рассказать немного теории:
В python есть два основных способа узнать однотипность переменных:
1) запросить их тип c помощью type() и сравнить результат
2) проверить “совместимость” данных с помощью isinstance()
Разница между методами в строгости проверки. В то время как type() при сравнении требует строгого соответствия, isinstance() скажет, что bool и int это один и тот же тип.
В рамках решения этой задачи, никакой разницы между использованиями этих методов нет. Кроме того, если попробовать напрямую сравнить type(a) == type(b), ты мы получим предупреждение о том, что сравнивать типы нехорошо, и лучше использовать is, но возможно даже, стоит использовать isinstance(). Как относиться к этой ситуации и что использовать – решать вам. Случаи ложного срабатывания isinstance() довольно экзотические. В подавляющем большинстве случаев вы не заметите никакой разницы. Сам я предпочитаю type() из-за более строгой проверки
Итак, смысл алгоритма в том, чтобы сравнить тип первого элемента с типом остальных. С учетом наших знаний задача достаточно простая – узнаем тип первого элемента, в цикле перебираем типы оставшихся элементов и если находим отличный от первого, возвращаем ошибку.
Для проверки элементов можно использовать еще два разных способа – функцию all() или списочное выражение, выдающее на выходе множество типов данных, если длина множества больше единицы – значит у нас разнотипные данные.
Посмотреть код
Решение
def same_type(func):
def wrapper(*args):
type_of_first = type(args[0])
if all(type(item) == type_of_first for item in args[1:]):
return func(*args)
else:
print('Обнаружены различные типы данных')
return wrapper
Решение
def same_type(func):
def wrapper(*args):
if len({type(item) for item in args}) != 1:
print("Обнаружены различные типы данных")
return False
return func(*args)
return wrapper