如何让Mypy按预期处理函数中的子类

2024-09-28 13:28:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下代码:

from typing import Callable

MyCallable = Callable[[object], int]
MyCallableSubclass = Callable[['MyObject'], int]

def get_id(obj: object) -> int:
    return id(obj)

def get_id_subclass(obj: 'MyObject') -> int:
    return id(obj)

def run_mycallable_function_on_object(obj: object, func: MyCallable) -> int:
    return func(obj)

class MyObject(object):
    '''Object that is a direct subclass of `object`'''
    pass

my_object = MyObject()

# works just fine
run_mycallable_function_on_object(my_object, get_id)

# Does not work (it runs, but Mypy raises the following error:)
# Argument 2 to "run_mycallable_function_on_object" has incompatible type "Callable[[MyObject], int]"; expected "Callable[[object], int]"
run_mycallable_function_on_object(my_object, get_id_subclass)

既然MyObjectobject继承,为什么MyCallableSubclass不能在MyCallable的每个地方工作?你知道吗

我读了一些关于Liskov substitution principle的书,也参考了Mypy docs关于协方差和逆方差的书。然而,即使在文档中,他们也给出了一个非常相似的例子

Callable is an example of type that behaves contravariant in types of arguments, namely Callable[[Employee], int] is a subtype of Callable[[Manager], int].

那么为什么用Callable[[MyObject], int]而不是Callable[[object], int]在Mypy中抛出错误呢?你知道吗

总的来说,我有两个问题:

  1. 为什么会这样?你知道吗
  2. 我该怎么修?你知道吗

Tags: ofrunidobjgetreturnobjecton
1条回答
网友
1楼 · 发布于 2024-09-28 13:28:42

当我写这个问题的时候,我意识到了问题的答案,所以我想我还是会问这个问题,然后再回答,这样可以节省人们以后问类似问题的时间。你知道吗

发生什么事了?

请注意Mypy文档的最后一个示例:

Callable is an example of type that behaves contravariant in types of arguments, namely Callable[[Employee], int] is a subtype of Callable[[Manager], int].

这里,Manager子类来自Employee。也就是说,如果某个东西期望某个功能可以接纳管理者,那么它得到的功能如果过度概括,可以接纳任何员工,就没关系了,因为它肯定会接纳管理者。你知道吗

然而,在我们的例子中,MyObject子类来自object。因此,如果某个东西期望一个函数可以接受对象,那么如果它得到的函数超过了并且只能接受MyObject,那就不好了

为什么?设想一个名为NotMyObject的类继承自object,但不继承自MyObject。如果一个函数应该能够接受任何对象,那么它应该能够同时接受NotMyObjectMyObject两个对象。但是,特定于函数只能接受MyObject对象,因此在这种情况下不起作用。你知道吗

我该怎么修?

Mypy是正确的。您需要使用更具体的函数(MyCallableSubclass)作为类型,否则您的代码可能会有bug,或者您的键入不正确。你知道吗

相关问题 更多 >

    热门问题