类型化:在python中更改继承类中字段的类型

类型化:在python中更改继承类中字段的类型,python,typing,python-typing,Python,Typing,Python Typing,让我们来看看: class A: pass class A2(A): @property def f(self): return None class B: def __init__(el: A) self._a = el class B2(B): def __init__(el: A2) super().__init__(el) def m(): self._a.f() 现

让我们来看看:

class A:
    pass

class A2(A):
    @property
    def f(self):
        return None

class B:
    def __init__(el: A)
        self._a = el

class B2(B):
    def __init__(el: A2)
        super().__init__(el)

    def m():
        self._a.f()
现在,我在调用self.\u a.f()时在最后一行出现键入错误,说“无法访问类型a的成员f”,即使它在B中的A2处声明,并且它具有该成员。
声明此代码段以便键入工作的正确方法是什么?

A
没有成员
f
,因此尝试访问
\u A.f
其中
\u A:A
是错误的。为了实现您想要的,您应该将
f
定义为
A
上的未实现函数,其子类应该实现:

A类:
@财产
def f(自我):
引发未实现的错误
或者用一种抽象的方法把它变成一个

从abc导入abc,abstractmethod
A类(ABC):
@财产
@抽象方法
def f(自我):。。。
这将通知类型检查器
A
及其所有子类都有一个成员
f
,并且您的代码应该正确地进行类型检查

如果只想缩小B2.\u a的类型范围,这就足够了:

B2类(B):
_a:A2
#类的其余部分定义
...

您忘记了
在第一行
类A
之后。为什么在B2中将
f()
定义为
@property
?这真的很混乱,我会更新代码以消除混乱。F只是一个占位符名称,因为
self.\u a
被推断为
a
的一个实例,谢谢!这是唯一的选择吗?如果我不想扩展A的接口,那是因为除了B2之外没有其他类需要M方法吗?请考虑显式地注释< <代码> b2..a < < />代码>,在类体中添加<代码>:a2< /代码>(不在方法中!)。这就足够在我的机器上进行代码类型检查了(mypy0.812)。我已经编辑了我的答案以包含代码。