python - 这段代码是在哪个类中定义的?

标签 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

最佳答案

正如您已经发现的那样,使用 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/

相关文章:

python - pip 和 virtualenv 在错误的地方安装了部分 django

python - 在 QLineEdit 中拦截 contextMenuEvent() 时出现 __init_subclass__ 错误

c++ - 在不更改成员范围的情况下有条件地启用静态成员

c# - 列表输出 namespace 的名称,而不是其值

maven-2 - Maven 中父项目的最新版本

python - 如何在不返回函数的情况下访问函数内部的列表?

python - 如何提取已作为参数传递给 Python lambda 函数的函数名称?

c++ - 在类定义中使用结构的细节和好处

c++ - win32 api中的RemoveDirectory()函数在删除子目录后不会删除父目录

objective-c - 如何访问父类中声明的方法?