Python 更改继承成员的提示类型

Python 更改继承成员的提示类型,python,python-3.x,inheritance,warnings,type-hinting,Python,Python 3.x,Inheritance,Warnings,Type Hinting,假设我有一个类的类型提示成员,当我继承时,我想将该成员的提示类型更改为继承类型。可能吗 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

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

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.occulator.look_for_bone()
上生成一个IDE(PyCharm)警告:“未解析属性引用”look_for_bone“for class Animal”。但它运行良好:

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

找到一根骨头。
即使明确提到允许在
\uuuu init\uuuu
中注释实例变量,但在PyCharm中似乎不起作用。但是,使用mypy 0.761运行良好。所以我想这是一个特殊的问题

除了在
\uuuu init\uuuu
中的注释外,还可以在类主体本身中注释实例变量(请参阅)。这确实与PyCharm有关。因此,为了解决您的问题,您可以使用:

class Kenel(Home):
    occupant: Dog

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

它运行正常,因为在运行时检查了类型。PyCharm必须静态检查类型,这是不可能的。这可能是一个原因,但我也对这种行为的原因感兴趣。您使用的是什么类型的检查程序(或者PyCharm的哪个版本)?这在最新版本的
mypy
中运行良好。您还可以将
accounter:Dog
作为类变量添加到
Kenel
@a_guest.3.2谢谢!注释类对象中的实例变量似乎与我相反,但是PEP 536确实这样说,并且它确实有效。如果您想其他语言,如java或C++实例变量,也在类体中声明。而
键入
具有
ClassVar
,以避免类变量的歧义。