以下是我需要做的一个简单示例:
from typing import Callable, Any
class Data:
pass
class SpecificData(Data):
pass
class Event:
pass
class SpecificEvent(Event):
pass
def detect_specific_event(data: SpecificData, other_info: str) -> SpecificEvent:
return SpecificEvent()
def run_detection(callback: Callable[[Data, Any], Event]) -> None:
return
run_detection(detect_specific_event)
现在我得到一个警告:
Expected type '(Data, Any) -> Event', got '(data: SpecificData, other_info: str) -> SpecificEvent' instead
对我来说,这个警告似乎没有意义,因为SpecificData和SpecificEvent分别是数据和事件的子类型,所以一切都应该正常。有没有办法让这项工作如我所料?我的想法是这样做:
class OtherSpecificData(Data):
pass
class OtherSpecificEvent(Event):
pass
def detect_other_event(data: OtherSpecificData, other_info: str) -> OtherSpecificEvent:
return OtherSpecificEvent()
run_detection(detect_other_event)
因此run_detection
函数尽可能通用。现在,这给出了与上面相同的警告
参数子类型与返回子类型的方向相反
赋值应该比变量的预期类型更具体。 例如:
所以你应该:
我花了一段时间才记住要使用哪种类型,但我想知道您想使用哪种类型的cast
与它在其他语言中的使用不同,cast(x,y)不做任何事,但它告诉键入将y视为类型x。运行时,它是一个no-op,只返回y
就像编译语言一样,如果我阅读它,我会特别注意代码:这真的在运行时起作用吗?数据类型是否正确?:
SpecificData
,那么使用LSP注释的重复闭包是合适的。如果可以的话,铸造就可以了。您的最小示例缺少该位,但是如果您已经显示了实际数据通过print(data)
,那么我们就知道是否应用了LSP李>在这里,你基本上告诉打字,“接受我的话”,即
detect_specific_event
是一个Callable[[Data, Any], Event])
运行和类型检查的输出:
将cast更改为实际sig:
run_detection(cast((Callable[[SpecificData, Any], SpecificEvent]),detect_specific_event))
相关问题 更多 >
编程相关推荐