6

Method default arguments can be overridden apparently:

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

How is this possible ? Is it considered bad style ?

Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
  • Addendum (2014.11.23): The use case is a default argument added to modify a method behavior in legacy code - not meant to be set by the caller - should name it `_r` – Mr_and_Mrs_D Nov 23 '14 at 19:52

3 Answers3

14

You can change signatures of overridden methods in an arbitrary way. Python doesn't care:

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

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

but if you ask

Is it considered bad style ?

the answer is Yes, because it violates the important Liskov substitution principle:

if Deriv extends Base, you must be able to replace all occurrences of Base with Deriv without breaking your program.

In other words, a derived class must fulfill all contracts provided by the base class. Particularly, overridden methods must have same signatures and similar semantics. Since Python doesn't help you on that, you have to control that manually, with the help of your IDE (here Intellij IDEA):

enter image description here

To answer your specific question about overriding default params, I guess the answer is "it depends". If the param is an option that only used internally and doesn't affect the observable behavior of the object, there's nothing wrong about changing it:

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

class BigBuffer(Buffer):
    def __init__(self, init_size=1024):

on the other side, if the param substantially affects semantics, it's a part of the contract and shouldn't be overridden. For example, this code will be confusing

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):
georg
  • 211,518
  • 52
  • 313
  • 390
  • Pycharm? yes I use this. Re: I knew it's bad style to change signature (there is even a warning in Pycharm as shown in your image) but in this specific case I change the default value - no warning. I think it is legal as Derived.meth() should behave differently - I just achieve this by changing the default value... – Mr_and_Mrs_D Nov 22 '14 at 14:33
  • @Mr_and_Mrs_D: updated the answer to address your specific question. – georg Nov 22 '14 at 15:15
  • 1
    Thanks - is Intellij IDEA or Pycharm in the pic ? – Mr_and_Mrs_D Nov 22 '14 at 19:41
  • @Mr_and_Mrs_D: it's IDEA, ver. 12 (not the most recent). – georg Nov 22 '14 at 20:21
0

It is definitely allowed, but could be very confusing for your callers. Shouldn't they be able to use a D object as if it were a B object?

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
0

How is this possible ?
what is the mechanism ?

You simply overwrite whole method in derived class.

GingerPlusPlus
  • 5,336
  • 1
  • 29
  • 52