Страницы

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

понедельник, 9 декабря 2019 г.

Зачем нужен вызов “-> max(a,b)” при создании функции?

#python #python_3x #функции #max


Нашёл такой пример: 

def function(a:int,b:str,c:list) -> max(2,3):


Зачем используется -> max(...)?
    


Ответы

Ответ 1



В данной строке def function(a:int,b:str,c:list) -> max(2,3): :int, :str, :list, -> max(2,3) - это аннотации. Впервые они предлагаются к введению в Python в PEP 3107, но их назначение четко не регламентировалось (их интерпретация возлагалась на авторов сторонних инструментов). В качестве аннотации может использоваться любое синтаксически верное выражение Python. При запуске кода интерпретатором выражения, используемые в качестве аннотации, исполняются (поэтому могут вызывать ошибки во время исполнения, например выражение def f() -> max(None, 1): pass вызовет ошибку TypeError, пример от jfs), но никаким специальным образом интерпретатором не обрабатываются (т.е., например, интерпретатор сам не проверяет типы). Позже было более четко зафиксировано использование аннотаций как аннотаций типов (PEP 484), т.е. после аргументов функции через двоеточие пишем предполагаемый тип аргумента, после -> пишем тип возвращаемого значения функции. Опять же, интерпретатор их игнорирует, но аннотации типов могут использоваться такими инструментами как mypy или встроенным в PyCharm статическим анализатором кода, чтобы понимать, что в функцию передано (или возвращено) значение не того типа, которое предполагалось, и отображать это как ошибку или предупреждение. -> max(2,3) с моей точки зрения не несет никакой смысловой нагрузки. Это не аннотация типа, а просто аннотация. Что имел в виду автор примера - загадка. Скорее всего это просто пример использования аннотаций. Программно получить доступ к аннотациям функции можно через атрибут функции __annotations__: def function(a:int,b:str,c:list) -> max(2,3): pass print(function.__annotations__) Результат: {'a': , 'return': 3, 'c': , 'b': } Здесь видны прописанные для аргументов типы, и видно, что выражение max(2,3) вычислилось, поэтому в качестве аннотации для возвращаемого значения записалось просто 3.

Ответ 2



Как мы можем видеть, эта функция может принимать число - a:int, строку - b:str и список - c:list. Функция max() возвращает наибольшее значение. Это можно узнать из документации Обычно после стрелки указывают возвращаемое значение. Посудив логически, можно предположить, что данная функция обрабатывает 2 каких-то типа. То есть int и list или str и list. Либо же просто сравнивает 2 числа или 2 строки. И возвращает наибольшее значение из переданных данных. Но это не точно. То есть в общем виде функция может выглядеть примерно так: def function(a, b): if type(b) == list: lst = b[:] # или b.copy() lst.append(a) try: return max(lst) except ValueError: return "'>' not supported between instances of 'int' and 'str'" else: try: return max(a, b) except ValueError: return "'>' not supported between instances of 'int' and 'str'" То есть если мы передадим, например, число 5 и список из чисел [3, 7, 1, 0, 4, 2, -1, 8, -4], то функция вернёт нам наибольшее значение из переданных данных, то есть 8. При вызове, например, этой функции с числом 20 и этим же списком, на выходе мы получим число 20, так как оно больше, чем какое-либо из списка. Что конкретно всё же имелось ввиду в данном случае - не очень понятно. Такой тип написания документации к функции очень плох, ибо не раскрывает цели функции, а также не сообщает что и при каких условиях функция возвращает. Подробнее о документировании классов и функций можно узнать, перейдя по этой ссылке.

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

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