python 3.6 : Either I miss something either generic typing breaks super chaining for inheritance

标签 python generics inheritance super typing

首先,我运行了以下代码,运行良好:

class Monster:
    def __init__(self):
        self._can_do = []
        print("created a monster")
        super().__init__()

class Race(Monster):
    """ all races must derive from this """
    def __init__(self):
        super().__init__()
        print("created a race x")

class Human(Race):
    def __init__(self):
        super().__init__()
        self._can_do.append("Do nothing special !")
        print("created a human")

class Elf(Race):
    def __init__(self):
        super().__init__()
        self._can_do.append("Avoid sleep")
        print("created an elf")

class Class:
    """ all classes must derive from this """
    def __init__(self):
        super().__init__()
        print("created a class x")

class Fighter(Class):
    def __init__(self):
        super().__init__()
        self._can_do.append("Hit hard")
        print("created a fighter")

class Wizard(Class):
    def __init__(self):
        super().__init__()
        self._can_do.append("Cast spells")
        print("created a wizard")


class Hero(Human, Fighter):
    def __init__(self):
        x = super()
        print(f"super = {x}")
        super().__init__() 
    def speak(self):
        for action in self._can_do:
            print(f"I can {action} !")

print("creating hero 1 :")
hero1 = Hero()

print("hero 1 human fighter says :")
hero1.speak()

结果是:

creating hero 1 :  
created a monster  
created a class x  
created a fighter  
created a race x  
created a human  
hero 1 human fighter says :  
I can Hit hard !  
I can Do nothing special ! !  

然后我又做了一次,稍微改变了代码,如下所示,因为那是我想去的地方:

(使 Hero 类动态继承而不是静态继承)

import typing

class Monster:
    def __init__(self):
        self._can_do = []
        print("created a monster")
        super().__init__()

class Race(Monster):
    """ all races must derive from this """
    def __init__(self):
        super().__init__()
        print("created a race x")

class Human(Race):
    def __init__(self):
        super().__init__()
        self._can_do.append("Do nothing special !")
        print("created a human")

class Elf(Race):
    def __init__(self):
        super().__init__()
        self._can_do.append("Avoid sleep")
        print("created an elf")

class Class:
    """ all classes must derive from this """
    def __init__(self):
        super().__init__()
        print("created a class x")

class Fighter(Class):
    def __init__(self):
        super().__init__()
        self._can_do.append("Hit hard")
        print("created a fighter")

class Wizard(Class):
    def __init__(self):
        super().__init__()
        self._can_do.append("Cast spells")
        print("created a wizard")

RaceT = typing.TypeVar('RaceT', bound=Race)
ClassT = typing.TypeVar('ClassT', bound=Class)

class Hero(typing.Generic[RaceT, ClassT]):
    def __init__(self):
        super().__init__() 
    def speak(self):
        for action in self._can_do:
            print(f"I can {action} !")

print("creating hero 1 :")
hero1 = Hero[Human,Fighter]()

print("hero 1 human fighter says :")
hero1.speak()

这一次,一切都出错了:

creating hero 1 :  
hero 1 human fighter says :  
Traceback (most recent call last):  
  File "./test2.py", line 61, in <module>  
    hero1.speak()  
  File "./test2.py", line 54, in speak  
    for action in self._can_do:  
AttributeError: 'Hero' object has no attribute '_can_do'  
  • 似乎使用泛型类创建使得 super 无法找到父类初始值设定项,非?

  • 我错过了什么吗?

最佳答案

这不是通用类型的意思。当你声明

class Hero(typing.Generic[RaceT, ClassT]):
    ...

那么这意味着 Hero 有两个类型参数。它意味着 Hero[Human, Fighter]HumanFighter 的子类,或者List[int]int 的子类。通用类型不是动态调整类的父类(super class)的方法。

关于 python 3.6 : Either I miss something either generic typing breaks super chaining for inheritance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51790229/

相关文章:

java - 如何声明扩展泛型的类

c# - (open generic type) 没有指定参数的 typeof 泛型类型

c# - 泛型方法中的隐式类型转换

c# - 如何使用可以处理整数或字符串值的泛型创建抽象基类?

JavaScript 类继承 - 填充方法不起作用

python - 套接字接收 `nothing` : infinite loop

python - 菜单和 QtOpenGL.QGLWidget 之间的空间

python - 在 Python/Pandas/PostgreSQL 中将表名作为函数参数传递

c++ - 从派生类对象访问重写的基类成员

python - 不能在 Python 3.1 中使用 unichr