Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are method default arguments overridden in python?

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 ?

like image 306
Mr_and_Mrs_D Avatar asked Nov 22 '14 13:11

Mr_and_Mrs_D


People also ask

How does method overriding work in Python?

In Python method overriding occurs by simply defining in the child class a method with the same name of a method in the parent class. When you define a method in the object you make this latter able to satisfy that method call, so the implementations of its ancestors do not come in play.

What are the default arguments in Python?

Default values indicate that the function argument will take that value if no argument value is passed during the function call. The default value is assigned by using the assignment(=) operator of the form keywordname=value.

How are arguments passed in Python?

Python passes arguments by assignment. That is, when you call a Python function, each function argument becomes a variable to which the passed value is assigned.

What is default argument in Python with example?

Python Default Arguments Here is an example. def greet(name, msg="Good morning!"): """ This function greets to the person with the provided message. If the message is not provided, it defaults to "Good morning!" """ print("Hello", name + ', ' + msg) greet("Kate") greet("Bruce", "How do you do?")


1 Answers

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):
like image 166
georg Avatar answered Sep 29 '22 07:09

georg