[英]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)
可以同時接受A
和B
,而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.