Рассмотрим следующий фрагмент:
from typing import TypeVar
import numpy as np
T = TypeVar("T", float, np.ndarray)
def f(x: T) -> T:
"""
expects a float or an array and returns an output of the same type
"""
return x * 2
f(1) # ok
f(np.array([1, 2, 3])) # ok
def g(x: float | np.ndarray) -> float | np.ndarray:
"""
expects either a float or an array
"""
return f(x) / 2 # should be fine, but pyright complains about type
Я создал TypeVar, чтобы намекнуть, что f ожидает на входе число с плавающей запятой или массив и вернет выходные данные того же типа.
Подсказка типа в g более свободная. Он ожидает либо число с плавающей запятой, либо массив, и вернет число с плавающей запятой или массив, не ограничивая тип вывода типом ввода.
Интуитивно, настройка имеет смысл. Внутри определения функции g мы знаем, что ожидаем, что x будет либо числом с плавающей запятой, либо массивом, т. е. тем, что f ожидает в качестве входных данных. Однако когда я передаю x в f в последней строке, Пайрайт жалуется:
Аргумент типа "float | ndarray[Unknown] , Unknown]" нельзя назначить параметру "x" типа "T@f" в функции "f"
Тип "float | ndarray[Unknown, Unknown]" несовместим с ограниченным переменная типа "T"
Это удивительно и расстраивает, потому что это означает, что нельзя использовать мою функцию f, не проявляя особой осторожности в отношении как они пишут подсказки по типу.
Есть мысли, как решить эту проблему?
Изменить:
После комментария Brian61354270 я воссоздал по сути тот же пример, только без зависимости от numpy. Здесь вместо массива numpy мы используем Fraction:
from fractions import Fraction
from typing import TypeVar
T = TypeVar("T", float, Fraction)
def f(x: T) -> T:
"""
expects a float or a Fraction and returns an output of the same type
"""
return x * 2
f(1.0) # ok
f(Fraction(1, 2)) # ok
def g(x: float | Fraction) -> float | Fraction:
"""
expects either a float or a Fraction
"""
return f(x) / 2 # should be fine, but pyright complains about type
Опять же, Pyright сообщает, по сути, о той же проблеме:
Аргумент типа «float | Fraction» не может быть присвоен параметр "x" типа "T@f" в функции "f"
Тип "float | Fraction" несовместим с переменной ограниченного типа "T"
Интересно, что если вместо Fraction использовать int, проверка типа проходит:
from typing import TypeVar
T = TypeVar("T", float, int)
def f(x: T) -> T:
"""
expects a float or an integer and returns an output of the same type
"""
return x * 2
f(1.0) # ok
f(1) # ok
def g(x: float | int) -> float | int:
"""
expects either a float or an integer
"""
return f(x) / 2 # now its ok
Подробнее здесь: https://stackoverflow.com/questions/776 ... -in-python
Являются ли переменные типов и объединения типов несовместимыми в Python? ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Статическая проверка типов на предмет объединения типов и сопоставления с образцом
Anonymous » » в форуме Python - 0 Ответы
- 12 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Обнаружено два объекта, ориентированных на один и тот же путь с несовместимыми типами активов.
Anonymous » » в форуме C# - 0 Ответы
- 20 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Обнаружено два объекта, ориентированных на один и тот же путь с несовместимыми типами активов.
Anonymous » » в форуме C# - 0 Ответы
- 18 Просмотры
-
Последнее сообщение Anonymous
-