在类中的方法中,我需要调用定义该方法的类的 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
最佳答案
正如您已经发现的那样,使用 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 中的类的这些(大多数是不必要的)硬编码,也可以使用:
super().__init__()
这将始终调用实现它的下一个父类上的方法。当前类的父类不是 super 调用解析的下一个父类的情况确实很少见。
输出变为(缺少__file__
):
Foo.__init__()
class: Foo
stack: __init__
Bar.__init__()
Foo.__init__()
class: Bar
stack: __init__
Bar.__init__()
Foo.__init__()
class: Baz
stack: __init__
关于python - 这段代码是在哪个类中定义的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36918588/