我正在使用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)
,那会给我假,所以我可以马上提出错误。我的问题是,当我构建DSL时,或者如果我需要使用更复杂的检查,例如mypy
答案 0 :(得分:2)
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
构造,即使这样,仍然有一些工作要做。