【问题标题】:Subclass method not getting resolved子类方法没有得到解决
【发布时间】:2021-05-14 10:01:42
【问题描述】:

我有以下结构:

import abc


class AbstractParent:
    pass

class AbstractChild(AbstractParent):
    @abc.abstractmethod
    def foo(self):
        raise NotImplementedError()

class Child(AbstractChild):
    def foo(self):
        print('!')

class A:
    def __init__(self, x: AbstractParent):
        self.x = x

class B(A):
    def __init__(self, x: Child):
        super().__init__(x=x)
    
    def test(self):
        return self.x.foo()      # Unresolved attribute reference 'foo' for class 'AbstractParent'

我期望的是,由于ChildAbstractParent 的子类,并且Child 有一个方法foo,并且由于xB 类中被声明为Childfoo 能够被解析为Child 的方法。

相反,Pycharm 有一个视觉警告 Unresolved attribute reference 'foo' for class 'AbstractParent' 为什么它不能弄清楚x 是一个Childfoo 方法?

请注意,在 B 中设置 self.x = x 可以解决此问题。这是一个错误吗?

【问题讨论】:

  • 静态的,你不知道self.x的类型,因为super().__init__这个方法是由self.__mro__的运行时值决定的。
  • @chepner 你能想出什么办法来帮助这里的静态类型检查器,以便x 的类型被解析为Child
  • 在调用super.__init__()之后显式设置self.x = x?

标签: python pycharm type-hinting


【解决方案1】:

可以用泛型解决,看下面的例子:

from typing import Generic, TypeVar


T = TypeVar("T", bound=AbstractParent)


class A(Generic[T]):
    x: T
    
    def __init__(self, x: T):
        self.x = x


class B(A[Child]):
    def __init__(self, x):
        super().__init__(x=x)

    def test(self):
        return self.x.foo()

请随时提出任何问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-30
    • 2019-07-18
    • 2011-01-14
    • 2022-01-16
    • 1970-01-01
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多