python - 为支持子类的 Callable 类型提示?

标签 python python-typing

我想对一个方法进行类型提示,该方法可以接收对 A 或 A 的子类进行操作的 Callable:

def do(f: Callable[[A], None])

我也试过:

def do(f: Callable[[typing.Type[A]], None])

一个完整的虚拟示例如下所示:

class A:
    n = 1

class B(A):
    n = 2

def something_a(x: A):
    print(x.n)

def something_b(x: B):
    print(x.n)

def do(f: Callable[[A], None]):
    f(B())

do(something_a)  # ok
do(something_b)  # PyCharm type check warnning

最佳答案

正如宫城先生指出的那样—— 类型检查警告是正确的。

B 继承自 A,所以 something_a(x: A) 可以同时接受 AB,而 something_b(x: B) 只能接受 B。 (协方差)

如果我们将 something_b(x: B) 传递给 do(f: Callable[[A], None]),我们允许 something_b(x: B) 接受 A - 它不能。所以 something_b(x: B) 不能替代 something_a(x: A)。另一方面,将 something_a(x: A) 传递给需要 Callable[[B], None] 的函数是可以的。 (逆变)

做什么? - 使用泛型

AType = TypeVar('AType', bound=A)

def do_fixed(f: Callable[[AType], None]):
    pass

do_fixed(something_a)  # ok
do_fixed(something_b)  # ok

虽然我们确实收到了传递其他类型可调用对象的警告:

class C:  # not derived from A
    n = 1

def something_c(x: C):
    print(x.n)

do_fixed(something_c)  # type check warning

但我们仍然需要确保我们没有将 A 传递给 something_b,这可以通过以下方式实现:

def do_safer(f: Callable[[AType], None], v: AType):
    f(v)
    
do_safer(something_a, A())  # ok
do_safer(something_a, B())  # ok
do_safer(something_b, A())  # type check warning
do_safer(something_b, B())  # ok

关于python - 为支持子类的 Callable 类型提示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65927533/

相关文章:

带有kwargs的函数的python类型签名(typing.Callable)

python - 在 apache flink 中嵌入现有的 ML 模型

python - 如何使用 Python OpenCV 优化圆检测?

java - Java的翻译过程是什么?

python - 使用正则表达式反向搜索

python - 我可以使用另一个函数的类型信息作为 Python 中的返回类型吗?

python - 输入动态分配的属性

python - Pandas 的 Mypy/typeshed stub

python - 比较我的 python 中的两个列表

Python 类成员类型提示