这段代码定义的是什么类?

时间:2016-04-28 15:05:54

标签: python class parent super

在类的方法中,我需要调用定义方法的类的super(),而不是对象的类。我特别关心Python 2.x,但欢迎使用3.x解决方案。

我想拥有可以在整个项目中使用的通用样板文件,其中一个类从另一个类继承到未知深度。为了避免递归错误,我需要调用定义代码的当前类的父类,而不是self对象的父类。每个模块中有许多地方引用了当前的类名,因为扩展了许多方法,每个扩展方法都可以调用父类方法。

这里的演示失败了:

#!/usr/bin/env python

from inspect import stack

class Foo(object):
    def __init__(self):
        print "Foo.__init__()"
        print "file: %s" % __file__
        print "class: %s" % self.__class__.__name__
        print "stack: %s" % stack()[0][3]
        print

class Bar(Foo):
    def __init__(self):
        print "Bar.__init__()"
        super(type(self), self).__init__()

class Baz(Bar):
    pass


foo = Foo()
bar = Bar()
baz = Baz()

结果如下:

Foo.__init__()
file: ./class.py
class: Foo
stack: __init__

Bar.__init__()
Foo.__init__()
file: ./class.py
class: Bar
stack: __init__

Bar.__init__()
Bar.__init__()

# snip several hundred lines

Bar.__init__()
Bar.__init__()
Traceback (most recent call last):
  File "./class.py", line 24, in <module>
    baz = Baz()
  File "./class.py", line 16, in __init__
    super(type(self), self).__init__()

# snip several hundred lines

  File "./class.py", line 16, in __init__
    super(type(self), self).__init__()
  File "./class.py", line 16, in __init__
    super(type(self), self).__init__()
RuntimeError: maximum recursion depth exceeded while calling a Python object

1 个答案:

答案 0 :(得分:1)

正如您已经发现,使用type(self)会导致递归,因为Baz.__init__会定向到Bar.__init__,但在那里您想再次呼叫super(Baz, self).__init__ Bar.__init__所以你最终会得到一个无限递归。

通常情况下,您只会在不知道您称之为哪个类实例的情况下调用父级,因为否则您需要真正了解并修复MRO。您始终可以使用self.__class__self.__class__.__name__

找出称为方法的子类

解决问题非常简单:将super - 来电替换为:

super(Bar, self).__init__()

在python3中避免这些(大多数是不必要的)类的超级硬编码也可以使用:

super().__init__()

这将始终在实现它的 next 父类上调用该方法。很少有情况下当前类的父类不是超级调用解析的下一个父类。

然后输出变为(缺少__file__):

Foo.__init__()
class: Foo
stack: __init__

Bar.__init__()
Foo.__init__()
class: Bar
stack: __init__

Bar.__init__()
Foo.__init__()
class: Baz
stack: __init__