我想知道為什么在呼叫 super().__init__('abc')時,self.name是'abc',而在呼叫 super().override()時卻變成'Nicky'?
是不是因為在呼叫super().__init__('abc')的時候,派生實體還沒有被創建,所以基類的屬性被替代使用?
class Base()。
def __init__(self, name):
self.name = name
self.base = '基類'。
print('base', self.name)
def override(self)。
print('base-override', self.name)
class Derived(Base)。
def __init__(self, name, age)。
super().__init__('abc'/span>)
self.name = name
self.age = age
def override(self)。
super().override()
d = Derived('Nicky', 20) # 基地abc。
d.override() # Base-override Nicky。
uj5u.com熱心網友回復:
如果你加入更多的列印,你可以更好地理解它
class Base()。
def __init__(self, name):
print('Base1'/span>, self.__dict__)
self.name = name
self.base = 'base class'。
print('Base2'/span>, self.name, self.__dict__)
def override(self)。
print('base-override', self.name)
class Derived(Base)。
def __init__(self, name, age)。
print('Derived1'/span>, self.__dict__)
super().__init__('abc')
self.name = name
self.age = age
print('Derived2', self.name, self.__dict__)
def override(self)。
super().override()
d = Derived('Nicky', 20) # 基地abc。
d.override() # Base-override Nicky。
輸出
Derived1 {}
Base1 {}
Base2 abc {'name': 'abc'/span>, 'base'/span>: 'base class'}派生2 Nicky {'base class'}。
Derived2 Nicky {'name': 'Nicky', 'base': 'base class', 'age': 20}。
覆寫基類的Nicky
你的物件d的屬性name沒有不同的版本,都是指同一個值,不要混淆自己說name在父類和子類之間是不同的,畢竟它只是同一個物件,不管類的層次是什么。
這只是一個你在某個時間點上最后設定的問題。在這里,當你呼叫 super().__init__('abc') 時,你還沒有在你的 Derived.__init__() 中初始化 "Nicky" 這個名字,因此你先看到了 "abc" 的值。
uj5u.com熱心網友回復:
這與執行順序和你如何使用引數有關。一個類是一個資料的集合,并且有一些函式來處理這些資料。你可以使用super()來從父類中明確地呼叫一個實作。
__init__作為一個方法或name作為一個屬性沒有什么特別之處。你的呼叫順序如下:
Derived>Derived('Nicky', 20)使用object.__new__創建一個新的空物件,然后呼叫Derived.__init__(obj, 'Nicky', 20)。請記住,在這一點上,屬性字典是空的。Derived.__init__(obj, 'Nicky', 20)開始時,通過super()呼叫Base.__init__(obj, 'abc')。Base.__init__(obj, 'abc')設定obj.name為'abc',obj.base為'基礎類'。然后它回傳時在字典中設定了這兩個屬性。這就是第一個print發生的地方。Derived.__init__(obj, 'Nicky', 20)然后運行并設定obj.name為'Nicky', 和obj.age為20。然后它就會回傳。關鍵的一點是,obj.name與Base.__init__所處理的是同一個屬性:不同的方法,相同的資料。Derived('Nicky', 20)回傳新創建和初始化的物件,你把它賦值給d. 。
- 當你呼叫
d.override,或任何其他方法時,它可以訪問d.__dict__,因為之前的方法離開了它。
除了關于實體資料如何被存盤和傳遞的課程外,這也是關于如何設計初始化器的課程。通常情況下,你準確地呼叫super以避免在派生類中做不必要的作業。在__init__中,這意味著讓基類處理名稱資訊。這也意味著目前實作的 override 不應該存在:無論如何,基類的實作將在派生實體上被呼叫,如果這就是你要做的,你實際上不需要覆寫它:
<
class Base()。
def __init__(self, name):
self.name = name
self.base = '基類'。
print('Base', type(self), self.name)
def override(self)。
print('base-override', type(self), self.name)
class Derived(Base)。
def __init__(self, name, age)。
super().__init__(name)
self.age = age
我在你的列印輸出中添加了type(self),所以你可以看到這是一個Derived的實體,當你實體化Derived時,會呼叫Base方法。
uj5u.com熱心網友回復:
這里沒有什么神秘的。
你用name = 'abc'來創建基類,但是用'Nicky'來覆寫sef.name。
從這段代碼可以看出:
super().__init__('abc'/span>)
self.name = name
self.age = age
為了使self.name = name被執行,運算式super().__init__('abc')必須被完成。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/320072.html
標籤:
