Giovanni Di Milia
Giovanni Di Milia

Reputation: 14041

Is it a bad practice to change the number of arguments of an overridden class method in Python?

Let's say I have a class written in Python like this:

class Foo(object):
    """My fake class"""

    def mymethod(self, first_arg):
        """original method"""
        pass

Now let's say I define a new class that extends the previous one and I want to override mymethod:

class Bar(Foo):
    """My new class"""

    def mymethod(self, first_arg, second_arg):
        """overridden method"""
        return first_arg == second_arg

Is it a bad practice to change the number of arguments in the overridden method?

EDIT:

Is there any official "good practice" rule about this? I just saw that if you do something like this in pydev you get a warning, so I suppose there should be something "official".

Upvotes: 4

Views: 1153

Answers (2)

chepner
chepner

Reputation: 532013

Consider the following:

objects = [ Foo(), Foo(), Bar(), Bar(), Foo() ]

for obj in objects:
    obj.mymethod(some_value)

This should work, since a Bar object should be usable anywhere a Foo object is expected, but you will get an error when Bar.mymethod receives too few arguments. At the very least, you should give any additional parameters a default value so that they aren't strictly necessary. If a default value is not applicable, then you should define a new method, which could call the superclass's method as part of its implementation.

Upvotes: 4

BrenBarn
BrenBarn

Reputation: 251518

I would say it's a bad idea unless you provide default values for your extra arguments. The way you have it, if you make an instance of Bar, anyone who doesn't know about Bar and only knows that your object is a Foo (which it is) will get an error if they try to use mymethod. But if you do def mymethod(self, first_arg, second_arg="some default"), then they will be okay even if they don't pass the second argument.

If you're able to do this, it often means you're just adding "details" to the method, and calls that don't supply those details will still work in a default way.

If you cannot create an appropriate default argument value, I would take that as a sign that you are defining behavior different enough that you need to make a new method instead.

Upvotes: 5

Related Questions