方法默认参数显然可以被覆盖:
>>> 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
但如果你问
Is it considered bad style ?
答案是肯定的,因为它违反了重要的Liskov substitution principle :
if Deriv extends Base, you must be able to replace all occurrences of Base with Deriv without breaking your program.
换句话说,派生类必须履行基类提供的所有契约。特别是,重写的方法必须具有相同的签名和相似的语义。由于 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):
我是一名优秀的程序员,十分优秀!