Python:在多次派生后查询一个类的父类(“super()”不起作用)
我构建了一个使用基类的多个派生的类系统 (object->class1->class2->class3):
class class1(object):
def __init__(self):
print "class1.__init__()"
object.__init__(self)
class class2(class1):
def __init__(self):
print "class2.__init__()"
class1.__init__(self)
class class3(class2):
def __init__(self):
print "class3.__init__()"
class2.__init__(self)
x = class3()
它按预期工作并打印:
class3.__init__()
class2.__init__()
class1.__init__()
现在我想
object.__init__(self)
...
class1.__init__(self)
...
class2.__init__(self)
用这样的东西替换 3 行:
currentParentClass().__init__()
...
currentParentClass().__init__()
...
currentParentClass().__init__()
所以基本上,我想创建一个类系统,其中我 不必输入“classXYZ.doSomething()”。
如上所述,我想获得“当前班级的 父类”。
将三行替换为:
super(type(self), self).__init__()
不起作用(它总是返回父类 当前实例-> class2) 并将导致无穷无尽 循环打印:
class3.__init__()
class2.__init__()
class2.__init__()
class2.__init__()
class2.__init__()
...
那么有没有一个函数可以给我当前类的 父级?
感谢您的帮助!
亨利
--------------------
编辑:
@Lennart 好吧,也许我误解了你,但目前我认为我没有足够清楚地描述问题。所以这个例子可能会更好地解释它:
现在让我们创建另一个子类,
class class4(class3):
pass
如果我们从 class4 派生一个实例会发生什么?
y = class4()
我认为它清楚地执行:
super(class3, self).__init__()
我们可以将其翻译为:
class2.__init__(y)
这绝对不是目标(这将是 class3.__init__(y)
)
现在进行大量父类函数调用 - i不想在 super() 调用中使用不同的基类名称重新实现所有函数。
我还想提一下,我对 python 级系统有点陌生,所以我希望你对我有耐心。
I have built a class-system that uses multiple derivations of a baseclass
(object->class1->class2->class3):
class class1(object):
def __init__(self):
print "class1.__init__()"
object.__init__(self)
class class2(class1):
def __init__(self):
print "class2.__init__()"
class1.__init__(self)
class class3(class2):
def __init__(self):
print "class3.__init__()"
class2.__init__(self)
x = class3()
It works as expected and prints:
class3.__init__()
class2.__init__()
class1.__init__()
Now I would like to replace the 3 lines
object.__init__(self)
...
class1.__init__(self)
...
class2.__init__(self)
with something like this:
currentParentClass().__init__()
...
currentParentClass().__init__()
...
currentParentClass().__init__()
So basically, i want to create a class-system where i
don't have to type "classXYZ.doSomething()".
As mentioned above, I want to get the "current class's
parent-class".
Replacing the three lines with:
super(type(self), self).__init__()
does NOT work (it always returns the parent-class of the
current instance -> class2) and will result in an endless
loop printing:
class3.__init__()
class2.__init__()
class2.__init__()
class2.__init__()
class2.__init__()
...
So is there a function that can give me the current class's
parent-class?
Thank you for your help!
Henry
--------------------
Edit:
@Lennart
ok maybe i got you wrong but at the moment i think i didn't describe the problem clearly enough.So this example might explain it better:
lets create another child-class
class class4(class3):
pass
now what happens if we derive an instance from class4?
y = class4()
i think it clearly executes:
super(class3, self).__init__()
which we can translate to this:
class2.__init__(y)
this is definitly not the goal(that would be class3.__init__(y)
)
Now making lots of parent-class-function-calls - i do not want to re-implement all of my functions with different base-class-names in my super()-calls.
I also want to mention that I am kind of new to pythons-class system, so i hope you have patience with me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
“如上所述,我想获取‘当前班级的父班级’。”
但你知道。在class2中它是class1。所以你想调用class1。总是。那么你就可以调用class1。
但获取当前类的父类的正确方法是 super()。但是你这样使用它:
这将为你提供 self 类的父类。在你的例子中, self 的类是 class3 ,所以正如你所注意到的,它总是返回 class2 。正确的使用方法如下:
使用 super() 和直接调用类之间的区别在于是否在层次结构中的某个位置使用多重继承。 Super 然后会找出哪个是正确的类别。
更新:
当您定义 class4 并调用它时会发生什么?
正如您所说,目标是调用
class3.__init__()
。这正是所发生的情况,因为根据正常的继承规则,class4 将从 class3 继承__init__
。您期望
class2.__init__()
被调用,但我不明白为什么您会这样期望。您继承自 class3,因此它的__init__
将被调用。它依次根据设计调用class2.__init__
。"As mentioned above, I want to get the "current class's parent-class"."
But you know it. In class2 it's class1. So you want to call class1. Always. So then you could just call class1.
But the correct way to the the current class's parent-class is super(). But you used it like this:
And that will get you the parent class of the class of self. And the class of self in your case is class3, so as you note, it always return class2. The correct way of using it is as follows:
The difference between using super() and calling the class directly is if you are using multiple inheritance somewhere in the hierarchy. Super will then figure out which is the correct class.
Update:
What happens when you define a class4 and call it?
As you say, the goal is to call
class3.__init__()
. This is exactly what happens, as class4 will inherit__init__
from class3, according to normal inheritance rules.You expected
class2.__init__()
to get called, but I don't understand why you expect that. You inherit from class3, so it's__init__
will be the one that is called. It in turn callsclass2.__init__
per design.您正在寻找
__class__
的__bases__
成员。您的班级的父级可以这样使用:但是,请记住您的班级可以有多个父级。
在我看来,你所做的事情很少值得。但了解 Python 本身如何跟踪多重继承所需的工具是很有趣的。
You are after the
__bases__
member of__class__
. The parent of your class is available like this:But, remember your class can have multiple parents.
What you are up to is, in my opinion, seldom worthwhile. But it is fun to know how Python itself keeps track of the furniture needed for multiple inheritance.
如果没有框架检查,你就无法做到这一点,而这是令人不悦的。
这是我在网上找到的一个进行框架检查的实现:
使用它时的代码:
On python3,
super()
已经很神奇了并且可以在不传递类的情况下工作:You can't do it without frame inspection, and that's frowned upon.
Here's a implementation I found on the net that does frame inspection:
Your code when using it:
On python3,
super()
is already magical and can work without passing the class: