我試圖使用增強而不是重寫基類的子類。我正在使用super
方法來調用基類。我發現我需要使用__init__
中的名稱修改功能(但僅在init中)才能使代碼正常工作。因此,我做了這個打印的例子。因爲我沒有使用名字改編我期望它來調用子類兩次,當我做初始化,而是調用基類在__init__中的python名稱mangling似乎不一致
似乎__init__
有時出現的基類,有時看到子類。我相信這只是我的一個不完全的理解,但是當我在打印示例中調用基類和子類時,是否需要爲真實代碼命名?
代碼
class base:
def __init__(self):
self.print()
def print(self):
print("base")
class subclass(base):
def __init__(self):
super(subclass, self).__init__()
self.print()
def print(self):
super(subclass, self).print()
print("subclass")
x = base()
x.print()
print("--")
y = subclass()
y.print()
輸出 - 爲什麼不y = subclass()
打印subclass
而不是base
,因爲我沒有使用名字改編?
> ./y.py
base
base
--
base
subclass
base
subclass
base
subclass
斷碼的時候我不使用名稱改編,作品,當我用self.__set
和__set = set
(註釋代碼)。它得到以下錯誤,當我不使用__set
:
File "./x.py", line 5, in __init__
self.set(arg)
TypeError: set() missing 1 required positional argument: 'arg2'
代碼:
class base:
def __init__(self, arg):
self.set(arg)
# self.__set(arg)
# __set = set
def set(self, arg):
self.arg = arg
def print(self):
print("base",self.arg)
class subclass(base):
def __init__(self, arg1, arg2):
super(subclass, self).__init__(arg1)
self.set(arg1, arg2)
def set(self, arg1, arg2):
super(subclass, self).set(arg1)
self.arg2 = arg2
def print(self):
super(subclass, self).print()
print("subclass", self.arg2, self.arg)
x = base(1)
x.print()
x.set(11)
x.print()
y = subclass(2,3)
y.print()
y.set(4,5)
y.print()
======= =======更新
我重寫了代碼看起來像這樣:
class base:
def __init__(self):
print("base init")
self.print()
def print(self):
print("base print")
class subclass(base):
def __init__(self):
print("sc init")
super(subclass, self).__init__()
print("sc after super")
self.print()
def print(self):
print("subclass print start")
super(subclass, self).print()
print("subclass print")
y = subclass()
print("--")
y.print()
,當我跑我得到這個輸出:
sc init
base init
subclass print start <<<< why is the subclass print called here
base print
subclass print
sc after super
subclass print start
base print
subclass print
--
subclass print start
base print
subclass print
爲什麼當我啓動子類時,底層init中的self.print
調用子類打印?我期待那個打印基地。當我在init之外調用它時,它會調用基本打印。
我打電話給兩個打印看看會發生什麼。我正在研究調用超類版本來理解流程。我認爲你打我的問題,雖然。基類有一個arg,而子類有兩個。當我試圖通過超級調用基類時,該方法有2個參數,並且沒有匹配。我將不得不考慮那一刻。仍然有點困惑,爲什麼名字mangling使它的工作。 – kdubs
@kdubs:這個名字讓它變得可行,因爲在名稱改變的情況下,這個方法的每個版本本質上是分開的,並且不能被子類覆蓋。所以每個類都會一直在調用它自己的實現。但這通常不是你想要的,因爲子類不能覆蓋基類實現。基本的問題是你不能採用一個需要一個參數的方法,並用一個需要兩個參數的方法來覆蓋它;任何用一個調用它的代碼現在都會失敗。 (在很多情況下,這可以通過爲第二個參數給出默認值來處理。) – BrenBarn
請參閱我的更新。打印在init函數中的調用不會按照我期望的方式工作 – kdubs