gpt4 book ai didi

python - 如何在 python 中继承类型提示?

转载 作者:太空狗 更新时间:2023-10-30 00:18:41 25 4
gpt4 key购买 nike

所以我的问题是,当我有一个类型为 A 的类时,我将这些函数用作 subclass(B) 它们仍然是类的类型A 并且不接受我的类 B 对象作为参数或函数签名。

我的问题简化了:

from typing import TypeVar, Generic, Callable

T = TypeVar('T')


class Signal(Generic[T]):
def connect(self, connector: Callable[[T], None]) -> None:
pass

def emit(self, payload: T):
pass


class A:
def __init__(self) -> None:
self.signal = Signal[A]()

def do(self) -> None:
self.signal.emit(self)

def handle_b(b: "B") -> None:
print(b.something)

class B(A):
def __init__(self) -> None:
super().__init__()
self.signal.connect(handle_b)

@property
def something(self) -> int:
return 42

我也可以提供完整的信号类,但这只会分散人们对问题的注意力。这使我在 mypy 中出现一个错误:

error: Argument 1 to "connect" of "Signal" has incompatible type Callable[[B], None]; expected Callable[[A], None]

由于信号处理是在 A 中实现的,因此子类 B 不能期望返回 B 类型的对象,即使它显然应该返回没事...

最佳答案

传递给 Signal[A]connectorCallable[[A], None] 类型,这意味着它必须 promise 能够处理 A 的任何实例(或其任何子类)。 handle_b 不能实现这个 promise ,因为它只适用于 B 的实例,因此它不能用作 信号的 连接器 类型为 Signal[A]

据推测,B 的任何实例的信号连接器 只会被要求处理B 的实例,因此它不需要是 Signal[A] 类型,但 Signal[B] 就足够了。这意味着 signal 的类型不是固定的,而是随着 A 的不同子类而变化,这意味着 A 需要是通用的。

The answer by ogurets正确地使 A 成为泛型,但是 do 没有问题,因为不清楚 self 是否是 self 期望的类型。 signal.emit.我们可以 promise ,通过使用用于 Signal 的相同类型变量注释 self,这些类型将始终匹配。通过使用由 A 绑定(bind)的新类型变量 _A,我们告诉 mypy self 将始终是 A< 的子类型 因此有一个属性 signal

from __future__ import annotations

from collections.abc import Callable
from typing import TypeVar, Generic

T = TypeVar('T')


class Signal(Generic[T]):
def connect(self, connector: Callable[[T], None]) -> None:
pass

def emit(self, payload: T):
print(payload)

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

class A(Generic[_A]):
signal: Signal[_A]

def __init__(self) -> None:
self.signal = Signal[_A]()

def do(self) -> None:
self.signal.emit(self)

def handle_b(b: "B") -> None:
print(b.something)

class B(A['B']):
def __init__(self) -> None:
super().__init__()
self.signal.connect(handle_b)

@property
def something(self) -> int:
return 42

b = B()
reveal_type(b.signal) # Revealed type is '...Signal[...B*]'

关于python - 如何在 python 中继承类型提示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47896283/

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