rocktheparty
rocktheparty

Reputation: 227

Method overloading with the same signature in python

class testClass(object):
    def test1(self):
        print "1"
    def test1(self):
        print "2"
    def test1(self):
        print "3"

This is a Class containing three methods which all have the same name (and even same signature)

When I call this:

tc = testClass()
tc.test1()

it's not throwing any error, but simplt printing 3.

One more example:

class testClass(object):
    def test1(self, a, b):
        print "1"
    def test1(self, a):
        print "2"
    def test1(self, a, b, c):
        print "3"

Again if I call tc.test1(), it raises an exception:

TypeError: test1() takes exactly 4 arguments (1 given)

So can I assume that in these situations it will always execute the last method defined in the class?

PS: I tried the same with individual functions in a file and got the same result, it executed the last function.

Upvotes: 5

Views: 1793

Answers (2)

Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Reputation: 160567

Yes, when Python encounters a class statement, it executes the def statements in order to create the correct name bindings for the ensuing class namespace (__dict__).

As with running the interpeter, names that get re-defined lose their old value; it gets replaced with the most recent assignment to that specific name.

There's no method overloading in python, because we have those nice keyword arguments that allow us make 'overloaded' calls however we need them:

class A:
    def f(self, a, b=None, c=None, d=None):
        print(a, b, c, d, sep=" | ")


a = A()

a.f(1)
# out : 1 | None | None | None

a.f(1, 2)
# out : 1 | 2 | None | None

a.f(1, 2, 3)
# out : 1 | 2 | 3 | None

a.f(1, 2, 3, 4)
# out : 1 | 2 | 3 | 4

As a final note, just because Python doesn't offer you inherent overloading it doesn't mean that you can't implement the functionality yourself.

After a bit of searching I found a nice example of this in this repo that exposes an @overloaded and @overloads(func) decorator for overloading functions:

from overloading import *

@overloaded
def f():
    return 'no args'

@overloads(f)
def f(foo):
    return 'one arg of any type'

@overloads(f)
def f(foo:int, bar:int):
    return 'two ints'

>>> f()
'no args'
>>> f('hello')
'one arg of any type'
>>> f('hello', 42)
TypeError: Invalid type or number of arguments when calling 'f'.

Got to love the Python Community.

Upvotes: 7

DeepSpace
DeepSpace

Reputation: 81654

So can I assume that in these situation it will always execute last method in the class?

You got that right. Your first example is equivalent to:

x = 1
x = 2
x = 3
print x
>> 3

Upvotes: 3

Related Questions