Nei*_*l G 12 python mypy python-typing
使用以下示例:
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
Run Code Online (Sandbox Code Playgroud)
MyPy 说:
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]")
Run Code Online (Sandbox Code Playgroud)
我不确定我是否同意这个问题的前提。
\n\nHere\xe2\x80\x99s 3.8文档字符串的一部分
\n\nclass TypeVar(_Final, _Immutable, _root=True):\n """Type variable.\n Usage::\n T = TypeVar(\'T\') # Can be anything\n A = TypeVar(\'A\', str, bytes) # Must be str or bytes\n\n ....\n def __init__(self, name, *constraints, bound=None,\n covariant=False, contravariant=False):\n ....\n\nRun Code Online (Sandbox Code Playgroud)\n\n现在,如果你刚刚
\n\nThetaType = TypeVar(\'ThetaType\')\nXType = TypeVar(\'XType\')\nRun Code Online (Sandbox Code Playgroud)\n\n您是否认为 ThetaType 的使用应该被视为 XType 的使用,即使设置了 2 个不同的类型变量?为什么添加bound可选参数会自动将它们折叠在一起?源代码不以任何方式强制存在绑定或名称旁边的任何参数。
我不认为\xe2\x80\x99s打字/mypy\xe2\x80\x99s工作来推断你在类型声明中的意图,只是为了检查你的代码与你声明的类型意图。如果您希望它们相同,则仅声明 1 个 TypeVar。如果您确实有理由拥有 2,那么将它们视为相同可能会失去一些语义意义。
\n\nI\xe2\x80\x99ll 添加到它比在子类上匹配时bound具有更大的灵活性。constraints让\xe2\x80\x99s 说你\xe2\x80\x99用户定义了int的4个子类。Int1(int)、Int2、Int3、Int4...现在您\xe2\x80\x99决定对代码进行分区,其中某些代码应该只接受Int1和Int2。Typevarint12 可以在某种程度上表达这一点,即使您的子类都匹配bound=int.