如何在python中重写方法默认参数?

时间:2014-11-22 13:30:44

标签: python python-2.7 inheritance methods default-arguments

可以明显覆盖方法默认参数:

>>> 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

这怎么可能?它被认为是不好的风格吗?

3 个答案:

答案 0 :(得分:6)

您可以以任意方式更改已覆盖方法的签名。 Python并不关心:

class Base:
    def foo(self, x, y):
        pass

class Deriv(Base):
    def foo(self, blah=100):
        pass

但如果你问

  

它被认为是不好的风格吗?

答案是肯定的,因为它违反了重要的Liskov substitution principle

  

如果Deriv扩展Base,您必须能够在不破坏程序的情况下用Deriv替换所有出现的Base。

换句话说,派生类必须满足基类提供的所有契约。特别是,重写的方法必须具有相同的签名和类似的语义。由于Python无法为您提供帮助,因此您必须在IDE的帮助下手动控制(此处为Intellij IDEA):

enter image description here

要回答有关覆盖默认参数的具体问题,我想答案是"它取决于"。如果param是一个只在内部使用并且不会影响对象的可观察行为的选项,那么改变它就没有错:

class Buffer:
    def __init__(self, init_size=16):

class BigBuffer(Buffer):
    def __init__(self, init_size=1024):
另一方面,如果param实际上影响了语义,它就是合同的一部分,不应该被覆盖。例如,这段代码会令人困惑

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):

答案 1 :(得分:0)

绝对允许,但对于您的来电者来说可能会非常混乱。他们不应该像使用D对象一样使用B对象吗?

答案 2 :(得分:0)

  

这怎么可能?
  机制是什么?

您只需在派生类中覆盖整个方法。