Get the type of the super class in Python 3
我有一个基类,有两个派生自它的类。我希望基类的方法的行为有所不同,这取决于参数是否与派生类属于同一类型,或者仅是基类的实例,但类型不同。这是当前的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class MyBase: def __init__(self, foo: int): self.foo = foo def __eq__(self, other): return self.foo == other.foo class MyDerived_1(MyBase): def __init__(self, foo: int, bar: int): super().__init__(foo) self.bar = bar class MyDerived_2(MyBase): def __init__(self, foo: int, bar: int): super().__init__(foo) self.bar = bar def __eq__(self, other): if type(other) == type(self): return self.bar == other.bar elif isinstance(other, MyBase): return super().__eq__(other) else: return False |
在最后一行中,我必须显式地引用mybase。也许这很好,但我的理解是,"super"关键字的一个主要点是它应该允许您更改基类,而不必在类中重新编写任何内容。因此,也就是说,这个解决方案的一个潜在问题是,如果mybase被更改,那么init会很好,因为它称为"super",但是eq不会更新它的行为。
所以我试图用"type(super)"或"type(super())"替换"mybase",但这些并不引用超级类,而是引用对象"super"的类。
请注意,此问题不同于:
获取父类名称?获取python 3中未绑定方法对象的定义类等。
因为一旦对象被初始化,它们就在寻找父类。
我想我应该可以通过运行MRO找到超级班。但这似乎是一个糟糕的解决方案,因为我不是在寻找整个继承树,我只是想知道超级类的类型。
有没有办法从"超级"中提取信息?
首先,当遇到不支持的类型时,希望从
Numeric methods and rich comparison methods should return this value if they do not implement the operation for the operands provided. (The interpreter will then try the reflected operation, or some other fallback, depending on the operator.)
当
接下来,可以使用python 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class MyBase: # ... def __eq__(self, other): if not isinstance(other, __class__): # we can't handle the other type, inform Python return NotImplemented return self.foo == other.foo class MyDerived_2(MyBase): # ... def __eq__(self, other): if isinstance(other, __class__): # if other is an instance of MyDerived_2, only test for 'bar' return self.bar == other.bar # otherwise fall back to the base behaviour return super().__eq__(other) |
注意,我使用了
除了测试特定的类层次结构之外,您还可以依赖duck类型;如果另一个对象具有正确的属性名,那么假设它可以用于比较:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class MyBase: # ... def __eq__(self, other): try: self.foo == other.foo except AttributeError: # we can't handle the other type, inform Python return NotImplemented class MyDerived_2(MyBase): # ... def __eq__(self, other): try: self.bar == other.bar except AttributeError: # otherwise fall back to the base behaviour return super().__eq__(other) |
我认为您可能需要使用
1 2 3 4 5 6 7 8 | class MyDerived_2(MyBase): def mytree(self): print(inspect.getclasstree([self.__class__])) c = MyDerived_2(1, 2) c.mytree() |
此输出:
1 | [(<class '__main__.MyBase'>, (<class 'object'>,)), [(<class '__main__.MyDerived_2'>, (<class '__main__.MyBase'>,))]] |