Во многих задачах требуется контроль входных данных, в частности, несмотря на динамическую типизацию, их типов.
Разработайте декоратор 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
{type(item) for item in args}
я правильно понимаю, что код выше строковое выражение??
не гуглится: строковое выражение python
если не сложно объясните, пожалуйста
Да, все правильно.
В терминах Яндекса, это списочное выражение.
В английском языке это называется List Comprehension и на русский однозначного хорошего перевода не имеет, поэтому часто его называют как попало. в том числе и я.
теперь дошло что создаём set
значит повторяться не будет
Чекер (Flake8) и соответственно Яндекс ругается на конструкцию type(item) == a и не пропускает проверку. Избежал этого используя конструкцию type(item) is a. ну либо надо “включать” isinstance()
Раньше этот код срабатывал, видимо обновили черекер.
type(item) is хороший вариант на замену.
isistance может давать ложные срабатывания в дочерних классах и поэтому плохо подходит для строгой проверки соответствия типа. Для него int и bool один и тот же тип. В пайтоне это в принципе так, но в других языках программирования далеко не всегда.
Спасибо за интересное решение (проверка длины множества типов входных данных):
if len({type(item) for item in args}) != 1: