Вот пример, который я написал.
from typing import Tuple, List
def performances(
pt: Tuple[float, float] | List[Tuple[float, float]]
) -> float | list[float]:
if isinstance(pt, list):
output = []
for pt_i in pt:
output.append(performances(pt_i))
else:
output = pt[0] + pt[1]
return output
if __name__ == "__main__":
# This work as intended
t1 = performances((1, 2))
print(t1)
# This work as intended
t2 = performances([(1, 2), (3, 4)])
print(t2)
# This work while I was expecting it to throw a TypeError
t3 = performances((1, 2, 3, 4))
print(t3)
Как я могу применить проверку типов в этом случае, чтобы быть уверенным, что я принимаю только список кортежей с двумя элементами?
Я также пробовал без типов Tuple
и List
из typing
, просто используя list[tuple[float, float]]
, но результат тот же.
И:
from typing import Tuple, Iterable
type Point = Tuple[float, float]
def performances(pt: Point | Iterable[Point]) -> float | list[float]:
...
Но то же самое.
Наверное, я чего-то не понимаю в наборе текста, но не знаю, что именно. Спасибо.
Я использую Pytest для некоторого модульного тестирования моего кода, и этот конкретный тест проходит успешно, в то время как раньше мне приходилось отклонять тест из-за ошибок типа (я думаю? Может быть, это не так).
В Python аннотации типов не являются обязательными и, к сожалению, могут быть совершенно неверными. Отдельные приложения, такие как mypy илиpyright, позволяют использовать аннотации для статического анализа кода и, при условии корректности аннотаций, предупреждают вас об ошибках. Однако во время выполнения эти аннотации обычно полностью игнорируются (за исключением таких библиотек, как Pydantic, которые используют аннотации для логического управления). Pytest отвечает только за выполнение тестовых операторов и проверку утверждений. Pytest не проверяет корректность аннотаций типов.
Если вы хотите иметь возможность проверять эти типы во время выполнения, этот вопрос может быть полезен: извлечение данных из типизированных типов
в чем конкретно заключается ваш вопрос? В чем проблема?
Я думал, что хинтинг типов вызовет ошибку TypeError, но теперь я понял, что мне нужно проверить это с помощью средства проверки типов, например mypy
. Теперь у меня есть ошибки, показанные в ответе ниже, и мне интересно, как их исправить.
Типы выходных данных имеют два различных результата в зависимости от параметров. pt: Tuple[float, float]
ведет к float
, тогда как pt: List[Tuple[float, float]]
ведет к List[float]
.
Mypy и другие инструменты статического анализа не имеют хорошего способа определить, какая входная форма должна привести к какой выходной форме. Это приводит к ошибкам при вызове append(performances(pt_i))
, поскольку ваши инструменты статического анализа будут думать, что вы пытаетесь создать List[Union[float, List[float]]]
.
Хороший способ исправить это — использовать @overload
из модуля набора текста.
from typing import Tuple, List, overload
@overload
def performances(pt: Tuple[float, float]) -> float:
...
@overload
def performances(pt: List[Tuple[float, float]]) -> List[float]:
...
def performances(
pt: Tuple[float, float] | List[Tuple[float, float]]
) -> float | list[float]:
if isinstance(pt, list):
return list(map(performances, pt))
return pt[0] + pt[1]
Используя эту стратегию, инструменты статического анализа могут легче сопоставлять входные данные с фактическими выходными данными. См. мой предыдущий комментарий к вашему посту, чтобы узнать, почему одного Pytest недостаточно для проверки этого сценария.
Используете ли вы проверку типов для проверки этого? Python по своей сути не проверяет ошибки типов.