更改继承成员的提示类型

Change hinted type of inherited member

假设我有一个 class 的类型提示成员,当我继承时,我想将该成员的提示类型更改为继承类型。这可能吗?

class Animal:
    pass

class Dog(Animal):
    def look_for_bone(self):
        print("Found a bone.")

class Home:
    def __init__(self, occupant: Animal):
        self.occupant: Animal = occupant

class Kenel(Home):
    def __init__(self, occupant: Dog):
        super(Kenel, self).__init__(occupant)

        # Here I KNOW that the occupant isn't just an Animal, it's a Dog.
        self.occupant: Dog
        # I've also tried `assert isinstance(self.occupant, Dog)`
        # and `assert isinstance(occupant, Dog)`.

fenton = Dog()
k = Kenel(fenton)
print(type(k.occupant))
# I want my IDE to be able to tab-complete look_for_bone on k.occupant
k.occupant.look_for_bone()

以上代码在 k.occupant.look_for_bone() 上生成 IDE (PyCharm) 警告:"Unresolved attribute reference "look_for_bone" for class Animal"。但它运行良好:

<class '__main__.Dog'>
Found a bone.

尽管 PEP 526 明确提到允许在 __init__ 中注释实例变量,但这在 PyCharm 中似乎不起作用。不过,它在 mypy 0.761 上运行良好。所以我想这是一个 PyCharm 特定问题。

除了 __init__ 中的注释之外,还可以在 class 主体本身中注释实例变量(请再次参阅 PEP 526)。这确实适用于 PyCharm。因此,为了解决您的问题,您可以使用:

class Kenel(Home):
    occupant: Dog

    def __init__(self, occupant: Dog):
        super().__init__(occupant)