Mit folgendem Beispiel:
from typing import Callable, Generic, Type, TypeVar
ThetaType = TypeVar('ThetaType', bound=int)
XType = TypeVar('XType', bound=int)
class IteratedFunction(Generic[ThetaType, XType]):
def find_fixed_point(self,
theta: ThetaType,
x_init: XType) -> XType:
return x_init
def combinator(
iterated_function_cls: Type[
IteratedFunction[ThetaType, XType]]) -> Callable[
[IteratedFunction[ThetaType, XType]], XType]:
old_find_fixed_point = iterated_function_cls.find_fixed_point
def new_find_fixed_point(
iterated_function: IteratedFunction[ThetaType, XType],
theta: ThetaType,
x_init: XType) -> XType:
return old_find_fixed_point(iterated_function, theta, x_init)
return new_find_fixed_point
MyPy sagt:
a.py:25: error: Incompatible return value type (got "XType", expected "XType")
a.py:25: error: Argument 1 has incompatible type "IteratedFunction[ThetaType, XType]"; expected "IteratedFunction[ThetaType, XType]"
a.py:25: error: Argument 2 has incompatible type "ThetaType"; expected "ThetaType"
a.py:25: error: Argument 3 has incompatible type "XType"; expected "XType"
a.py:27: error: Incompatible return value type (got "Callable[[IteratedFunction[ThetaType, XType], ThetaType, XType], XType]", expected "Callable[[IteratedFunction[ThetaType, XType]], XType]")
python
mypy
python-typing
Neil G.
quelle
quelle
new_find_fixed_point
als würde mypy als generische Funktion mit einer eigenen separaten Instanziierung vonThetaType
und interpretiertXType
.Antworten:
Ich bin mir nicht sicher, ob ich der Prämisse dieser Frage zustimme.
Hier ist ein Teil des Docstrings von 3.8
Nun, wenn Sie nur hatten
Würden Sie argumentieren, dass die Verwendung von ThetaType als Verwendung von XType betrachtet werden sollte, obwohl 2 verschiedene Typevars eingerichtet wurden? Warum würde das Hinzufügen des
bound
optionalen Arguments sie automatisch wieder zusammenfassen? Die Quelle erzwingt in keiner Weise das Vorhandensein von gebundenen oder anderen Argumenten neben dem Namen.Ich glaube nicht, dass es die Aufgabe von typing / mypy ist, Ihre Absichten in Typdeklarationen abzuleiten , nur um Ihren Code mit Ihren deklarierten Typabsichten zu vergleichen . Wenn Sie meinen, dass sie gleich sind, deklarieren Sie nur 1 TypeVar. Wenn Sie sie als gleich betrachten, könnte dies eine semantische Bedeutung verlieren, wenn Sie tatsächlich Gründe hätten, 2 zu haben.
Ich werde hinzufügen, dass dies
bound
mehr Flexibilität ermöglicht,constraints
als es für Unterklassen gilt. Angenommen, Sie haben 4 Unterklassen von int benutzerdefiniert. Int1 (int), Int2, Int3, Int4 ... Jetzt haben Sie beschlossen, Ihren Code so zu partitionieren, dass ein Teil davon nur Int1 und Int2 akzeptieren sollte. Typevarint12 könnte dies etwas ausdrücken, obwohl alle Ihre Unterklassen übereinstimmenbound=int
.quelle