方法默認參數顯然可以覆蓋:如何在python中重寫方法默認參數?
>>> class B:
... def meth(self, r=True): print r
>>> class D(B):
... def meth(self, r=False): print r
... D().meth()
False
>>> B().meth()
True
這怎麼可能?它被認爲是不好的風格?
方法默認參數顯然可以覆蓋:如何在python中重寫方法默認參數?
>>> class B:
... def meth(self, r=True): print r
>>> class D(B):
... def meth(self, r=False): print r
... D().meth()
False
>>> B().meth()
True
這怎麼可能?它被認爲是不好的風格?
您可以以任意方式更改重寫方法的簽名。 Python並不關心:
class Base:
def foo(self, x, y):
pass
class Deriv(Base):
def foo(self, blah=100):
pass
但如果你問
是不是認爲是壞的風格?
答案是肯定的,因爲它違反了重要Liskov substitution principle:
如果DERIV延伸基地,你必須能夠取代DERIV基地的所有事件不會破壞你的程序。
換句話說,派生類必須滿足基類提供的所有契約。特別是,重寫的方法必須具有相同的簽名和相似的語義。由於Python不幫你,你必須手動控制,以你的IDE的幫助下(這裏的IntelliJ IDEA):
要獲得關於覆蓋默認參數,可以我想具體的問題答案是「視情況而定」。如果該參數是隻在內部使用,不影響物體的觀察行爲的選擇,沒有什麼錯要改變它:
class Buffer:
def __init__(self, init_size=16):
class BigBuffer(Buffer):
def __init__(self, init_size=1024):
在另一邊,如果帕拉姆大大影響語義,這是一個合同的一部分,不應被覆蓋。例如,該代碼將是混亂
class Test:
def test_equal(self, a, b, fail_if_equal=False):
class MyTest(Test):
def test_equal(self, a, b, fail_if_equal=True):
Pycharm?是的,我用這個。回覆:我知道改變簽名的風格很糟糕(甚至在圖像中顯示的Pycharm中有警告),但在這種特定情況下,我更改了默認值 - 沒有任何警告。我認爲這是合法的,因爲Derived.meth()應該有不同的行爲 - 我只是通過更改默認值來實現... – 2014-11-22 14:33:03
@Mr_and_Mrs_D:更新了答案以解決您的具體問題。 – georg 2014-11-22 15:15:28
謝謝 - 圖片中是Intellij IDEA或Pycharm嗎? – 2014-11-22 19:41:39
這是絕對允許的,但可能會讓您的呼叫者感到困惑。他們是不是應該能夠使用D
對象,就像它是一個B
對象一樣?
是的,永遠不會傳遞參數;) - 什麼是機制? – 2014-11-22 13:42:51
這怎麼可能?
什麼是機制?
您只需在派生類中覆蓋整個方法即可。
補遺(2014年11月23日):用例是一個默認參數添加到修改遺留代碼的方法的行爲 - 並不意味着由主叫方設置 - 應命名'_r' – 2014-11-23 19:52:43