在Python 3中,在调用super()之前重写父类属性
考虑下面的例子。在Python 3中,在调用super()之前重写父类属性,python,class,python-3.x,inheritance,attributes,Python,Class,Python 3.x,Inheritance,Attributes,考虑下面的例子。Parent类有一个名为attr的属性。Child1和Child2都有一个同名属性。Child1和Child2之间的唯一区别在于Child1在覆盖父级的attr属性之前调用super()Child2似乎不会覆盖父级的attr,因为该属性是在super()调用之前定义的。在调用super() class Parent(): def __init__(self): self.attr = "parent" class Child1(Parent):
Parent
类有一个名为attr
的属性。Child1
和Child2
都有一个同名属性。Child1
和Child2
之间的唯一区别在于Child1
在覆盖父级的attr
属性之前调用super()
<相反,code>Child2似乎不会覆盖父级的attr
,因为该属性是在super()
调用之前定义的。在调用super()
class Parent():
def __init__(self):
self.attr = "parent"
class Child1(Parent):
def __init__(self):
super().__init__()
self.attr = "child1"
class Child2(Parent):
def __init__(self):
self.attr = "child2"
super().__init__()
if __name__ == '__main__':
child1 = Child1()
print(child1.attr) # "child1"
child2 = Child2()
print(child2.attr) # "parent"
没有“家长的attr
”和“孩子的attr
”这样的东西。该实例上只有一个attr
,无论它是从父类中的代码设置的,还是从子类中的代码设置的,还是从没有该类的代码设置的
换句话说,这些示例产生相同的结果:
例1
例2
例3
实际答案;)
因此,Child1
和Child2
之间的区别在于Child1
的\uuuu init\uuu
执行以下操作:
self.attr = "parent"
self.attr = "child1"
而Child2
的\uuuu init\uuuu
有效地做到了这一点:
self.attr = "child2"
self.attr = "parent"
没有“家长的attr
”和“孩子的attr
”这样的东西。该实例上只有一个attr
,无论它是从父类中的代码设置的,还是从子类中的代码设置的,还是从没有该类的代码设置的
换句话说,这些示例产生相同的结果:
例1
例2
例3
实际答案;)
因此,Child1
和Child2
之间的区别在于Child1
的\uuuu init\uuu
执行以下操作:
self.attr = "parent"
self.attr = "child1"
而Child2
的\uuuu init\uuuu
有效地做到了这一点:
self.attr = "child2"
self.attr = "parent"
否。super()。\uuuu init\uuuu()
是调用超类的\uuuuuu init\uuuu
的缩写,将当前实例作为self
传递给它
考虑一下创建Child2
的实例时会发生什么。首先,创建该类的“裸”实例。必须初始化此实例。为此,Python将此实例作为self
传递给Child2.\uuu init\uu
。现在Child2.\uuuu init\uuuu
首先向该实例添加一个attr
属性。但是它接下来调用super()。\uuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。重要的是,self
是我们正在初始化的Child2
实例。因此Parent.\uuuu init\uuuu
然后覆盖此实例的attr
属性
通常,最好将super()。\uuuu init\uuuu()
调用放在子类的\uuuu init\uuu
中的第一位。这并不是一个真正的限制,大多数人都希望它能排在第一位
演示程序流程的示例:
class Parent(object):
def __init__(self):
print('Here I am, in the parent! My ID is: ' + str(id(self)))
class Child(Parent):
def __init__(self):
print('Initializing new Child instance with ID: ' + str(id(self)))
super().__init__()
这样,创建Child
的实例将打印出:
Initializing new Child instance with ID: 4372063120
Here I am, in the parent! My ID is: 4372063120
否。super()。\uuuu init\uuuu()
是调用超类的\uuuuuu init\uuuu
的缩写,将当前实例作为self
传递给它
考虑一下创建Child2
的实例时会发生什么。首先,创建该类的“裸”实例。必须初始化此实例。为此,Python将此实例作为self
传递给Child2.\uuu init\uu
。现在Child2.\uuuu init\uuuu
首先向该实例添加一个attr
属性。但是它接下来调用super()。\uuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。重要的是,self
是我们正在初始化的Child2
实例。因此Parent.\uuuu init\uuuu
然后覆盖此实例的attr
属性
通常,最好将super()。\uuuu init\uuuu()
调用放在子类的\uuuu init\uuu
中的第一位。这并不是一个真正的限制,大多数人都希望它能排在第一位
演示程序流程的示例:
class Parent(object):
def __init__(self):
print('Here I am, in the parent! My ID is: ' + str(id(self)))
class Child(Parent):
def __init__(self):
print('Initializing new Child instance with ID: ' + str(id(self)))
super().__init__()
这样,创建Child
的实例将打印出:
Initializing new Child instance with ID: 4372063120
Here I am, in the parent! My ID is: 4372063120