使用 typing 模块时如何检查类型兼容性?
How to check type compatibility when using the typing module?
我正在使用 Python PEP484 类型提示为我在 Python 中编写的 DSL 编写类型检查器。如果我有一个函数,其参数之一期望类型为 T
,并且使用类型为 S
的表达式调用它,我如何检查调用是否有效?使用 issubclass(S, T)
就够了吗?如果是这样,为什么 mypy
会有这么复杂的 is_subtype
检查?或者我应该只使用 mypy
版本?
编辑:这里有一个例子来阐明我的意思。 DSL 的函数定义为:
T = TypeVar('T', float, str)
def op_add(operand1: T, operand2: T) -> T:
"Number addition or string concatenation."
# In this DSL, `+` cannot be used with lists
return operand1 + operand2 # Rely on Python overloading of `+`
然后用户键入一个表达式,该表达式被解析为语法树,分支可能是:node = OperatorNode('+', Literal([5.0]), Variable("abc"))
。我们还不知道 abc
变量的值,但是列表永远不能与 +
一起使用,所以我想提出一个 TypeError
来提醒用户。
如果我这样做 issubclass(typing.List[float], var)
,那会给我 False,所以我可以立即提出错误。我的问题是,在我构建 DSL 时,是否可以保证此检查适用于各种情况,或者我是否需要使用更复杂的检查,例如 mypy
issubclass
如果 issubclass
的参数都不包含来自 typing
模块的构造,例如 Union
、Callable
、Any
,则检查就足够了、仿制药等
typing
构造存在于 python 运行时作为其真实形式的影子,即它们不支持许多在概念上有意义的操作:
issubclass(List[int], List[int]) # runtimem error
issubclass(List[int], List) # True (as expected)
issubclass(str, Union[str]) # runtime error
issubclass(Union[str], str) # True (as expected)
issubclass(Union[int, str], str) # runtime error
有时 issubclass
会与 typing
结构一起工作,但一般来说,它可能会引发异常或给出不正确的答案;您需要根据具体情况弄清楚该怎么做。
mypy
有一个更复杂的 is_subtype
因为它确实需要处理所有的 typing
构造,即使那样还有一些工作要做。
我正在使用 Python PEP484 类型提示为我在 Python 中编写的 DSL 编写类型检查器。如果我有一个函数,其参数之一期望类型为 T
,并且使用类型为 S
的表达式调用它,我如何检查调用是否有效?使用 issubclass(S, T)
就够了吗?如果是这样,为什么 mypy
会有这么复杂的 is_subtype
检查?或者我应该只使用 mypy
版本?
编辑:这里有一个例子来阐明我的意思。 DSL 的函数定义为:
T = TypeVar('T', float, str)
def op_add(operand1: T, operand2: T) -> T:
"Number addition or string concatenation."
# In this DSL, `+` cannot be used with lists
return operand1 + operand2 # Rely on Python overloading of `+`
然后用户键入一个表达式,该表达式被解析为语法树,分支可能是:node = OperatorNode('+', Literal([5.0]), Variable("abc"))
。我们还不知道 abc
变量的值,但是列表永远不能与 +
一起使用,所以我想提出一个 TypeError
来提醒用户。
如果我这样做 issubclass(typing.List[float], var)
,那会给我 False,所以我可以立即提出错误。我的问题是,在我构建 DSL 时,是否可以保证此检查适用于各种情况,或者我是否需要使用更复杂的检查,例如 mypy
issubclass
如果 issubclass
的参数都不包含来自 typing
模块的构造,例如 Union
、Callable
、Any
,则检查就足够了、仿制药等
typing
构造存在于 python 运行时作为其真实形式的影子,即它们不支持许多在概念上有意义的操作:
issubclass(List[int], List[int]) # runtimem error
issubclass(List[int], List) # True (as expected)
issubclass(str, Union[str]) # runtime error
issubclass(Union[str], str) # True (as expected)
issubclass(Union[int, str], str) # runtime error
有时 issubclass
会与 typing
结构一起工作,但一般来说,它可能会引发异常或给出不正确的答案;您需要根据具体情况弄清楚该怎么做。
mypy
有一个更复杂的 is_subtype
因为它确实需要处理所有的 typing
构造,即使那样还有一些工作要做。