gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 04:53:53 24 4
gpt4 key购买 nike

我想对一个方法进行类型提示,该方法可以接收对 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com