簡體   English   中英

支持子類的 Callable 的類型提示?

[英]Type hinting for a Callable that supports subclasses?

我想鍵入提示一個方法,該方法可能接收在 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

正如 Miyagi 先生指出的那樣 - 類型檢查警告是正確的。

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]的 function 就可以了。 逆變

該怎么辦? - 使用 Generics

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM