By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,086 Members | 1,460 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,086 IT Pros & Developers. It's quick & easy.

Method overloading?

P: n/a
Hi all,

Is it possible to be able to do the following in Python?

class Test:
def __init__(self):
pass

def puts(self, str):
print str

def puts(self, str,str2):
print str,str2

if __name__ == "__main__":
t = Test()
t.puts("hi")
t.puts("hi","hello")
Cheers

Feb 15 '07 #1
Share this Question
Share on Google+
11 Replies


P: n/a
On 2007-02-15, placid <Bu****@gmail.comwrote:
Is it possible to be able to do the following in Python?

class Test:
def __init__(self):
pass

def puts(self, str):
print str

def puts(self, str,str2):
print str,str2

if __name__ == "__main__":
t = Test()
t.puts("hi")
t.puts("hi","hello")
You tell us: what happened when you tried it?

And then what happens when you do this?

class Test:
def __init__(self):
pass

def puts(self, *args):
print ' '.join(args)

if __name__ == "__main__":
t = Test()
t.puts("hi")
t.puts("hi","hello")

Now an exercise for the gentle reader: change the puts method
so that this call works:

t.puts("hi",1,3.45)

--
Grant Edwards grante Yow! Yow! I'm imagining
at a surfer van filled with
visi.com soy sauce!
Feb 15 '07 #2

P: n/a
On Feb 15, 4:04 pm, Grant Edwards <gra...@visi.comwrote:
On 2007-02-15, placid <Bul...@gmail.comwrote:
Is it possible to be able to do the following in Python?
class Test:
def __init__(self):
pass
def puts(self, str):
print str
def puts(self, str,str2):
print str,str2
if __name__ == "__main__":
t = Test()
t.puts("hi")
t.puts("hi","hello")

You tell us: what happened when you tried it?
Well, when i run it i get this error "puts() takes exactly 3 arguments
(2 given)" which means that the second a time i try to define the
puts() method "overwrites" the first one
>
And then what happens when you do this?

class Test:
def __init__(self):
pass

def puts(self, *args):
print ' '.join(args)

if __name__ == "__main__":
t = Test()
t.puts("hi")
t.puts("hi","hello")
but this isn't overloading.
>
Now an exercise for the gentle reader: change the puts method
so that this call works:

t.puts("hi",1,3.45)

--
Grant Edwards grante Yow! Yow! I'm imagining
at a surfer van filled with
visi.com soy sauce!

Feb 15 '07 #3

P: n/a
On Feb 14, 10:54 pm, "placid" <Bul...@gmail.comwrote:
Hi all,

Is it possible to be able to do the following in Python?

class Test:
def __init__(self):
pass

def puts(self, str):
print str

def puts(self, str,str2):
print str,str2

if __name__ == "__main__":
t = Test()
t.puts("hi")
t.puts("hi","hello")

Cheers
No, Python does not do overloading as part of the language, you have
to do the variable argument interpretation for yourself.

For instance, if you want a method to accept a single argument of
various types, it would look something like this:

def multiAccept( argOfVariousTypes ):
if isinstance(argOfVariousTypes,int):
# treat like an int
elif isinstance(argOfVariousTypes,float):
# treat like a float
elif isinstance(argOfVariousTypes,(list,tuple)):
# treat like a container

This is not really all that Pythonic a style. More generally accepted
is to just *use* the arg in the way you want, and throw exceptions
when the arg doesn't conform - if the user sends invalid args, let him/
her deal with the resulting exceptions.

Here's a method that will handle an arg of various types:

def containerStats(cont):
print "Container is of type %s" % cont.__class__.__name__
print "- min value is", min(cont)
print "- max value is", max(cont)
print "- length is", len(cont)
>>containerStats( [1,2,3] )
Container is of type list
- min value is 1
- max value is 3
- length is 3
>>containerStats( ('abc', 'def', 123) )
Container is of type tuple
- min value is 123
- max value is def
- length is 3
>>containerStats( dict(zip("abc",range(3))) )
Container is of type dict
- min value is a
- max value is c
- length is 3
>>containerStats("lsjlsja;s")
Container is of type str
- min value is ;
- max value is s
- length is 9

What's really interesting, is that this method could have been written
back in Python 1.5 days, and in Python 2.3 with the introduction of
sets, we could use this new data type, which didn't even exist when
the original code was written, and get some interesting results:
>>containerStats(set("SLKFJDSLJDFSLJFSLKFS"))
Container is of type set
- min value is D
- max value is S
- length is 6
And if we don't send a container? This happens:
>>containerStats( 3.14159 )
Container is of type float
- min value is
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in containerStats
TypeError: iteration over non-sequence

But what did I expect, sending a single float to a method that clearly
expects a sequence of some kind?!

Python does include in the language the ability to send a variable
number of arguments to a method, using *args and **kwargs. Your
original puts method can accept a variable argument list in something
like this:

class Test:
def __init__(self):
pass

def puts(self, *args):
print " ".join(map(str,args))

if __name__ == "__main__":
t = Test()
t.puts("hi")
t.puts("hi","hello")
t.puts("hi",1,3.45)

Prints:
hi
hi hello
hi 1 3.45

Combine these techniques, and you can overload your methods to your
heart's content!

-- Paul
Feb 15 '07 #4

P: n/a
On Wed, 14 Feb 2007 21:12:39 -0800, placid wrote:
On Feb 15, 4:04 pm, Grant Edwards <gra...@visi.comwrote:
>On 2007-02-15, placid <Bul...@gmail.comwrote:
Is it possible to be able to do the following in Python?
class Test:
def __init__(self):
pass
def puts(self, str):
print str
def puts(self, str,str2):
print str,str2
if __name__ == "__main__":
t = Test()
t.puts("hi")
t.puts("hi","hello")

You tell us: what happened when you tried it?

Well, when i run it i get this error "puts() takes exactly 3 arguments
(2 given)" which means that the second a time i try to define the
puts() method "overwrites" the first one
Yes, that's right. It is no different from doing this:

x = 1
x = 2

>And then what happens when you do this?

class Test:
def __init__(self):
pass

def puts(self, *args):
print ' '.join(args)

if __name__ == "__main__":
t = Test()
t.puts("hi")
t.puts("hi","hello")

but this isn't overloading.
Neither was your first example.
This is an example of overloading:

class Cheese(object):
def flavour(self):
return "tasty and scrumptious"
def colour(self):
return "yellow"
Now we define a sub-class which overloads some methods:

class BlueVein(Cheese):
def colour(self):
return "white with blue veins"

Testing it:

>>c = BlueVein()
c.flavour() # inherited from the super class
'tasty and scrumptious'
>>c.colour() # over-ridden by the sub-class
'white with blue veins'
>>super(BlueVein, c).colour() # call the super class method
'yellow'
I hope this helps.

--
Steven D'Aprano

Feb 15 '07 #5

P: n/a
On Wed, 14 Feb 2007 21:58:35 -0800, Paul McGuire wrote:
No, Python does not do overloading as part of the language, you have
to do the variable argument interpretation for yourself.

For instance, if you want a method to accept a single argument of
various types, it would look something like this:

def multiAccept( argOfVariousTypes ):
if isinstance(argOfVariousTypes,int):
# treat like an int
elif isinstance(argOfVariousTypes,float):
# treat like a float
elif isinstance(argOfVariousTypes,(list,tuple)):
# treat like a container
Is that really called "overloading"? I've never (knowingly) come across
the term being used in that context before. I've always known that as
"multiple dispatch" or "polymorphism", depending on whether you or the
compiler handles the dispatching.

Actually, I tell a lie. I've always know it as "a function that can handle
different types of arguments" :)

--
Steven D'Aprano

Feb 15 '07 #6

P: n/a
On Feb 15, 12:23 am, Steven D'Aprano
<s...@REMOVEME.cybersource.com.auwrote:
On Wed, 14 Feb 2007 21:58:35 -0800, Paul McGuire wrote:
No, Python does not do overloading as part of the language, you have
to do the variable argument interpretation for yourself.
For instance, if you want a method to accept a single argument of
various types, it would look something like this:
def multiAccept( argOfVariousTypes ):
if isinstance(argOfVariousTypes,int):
# treat like an int
elif isinstance(argOfVariousTypes,float):
# treat like a float
elif isinstance(argOfVariousTypes,(list,tuple)):
# treat like a container

Is that really called "overloading"? I've never (knowingly) come across
the term being used in that context before. I've always known that as
"multiple dispatch" or "polymorphism", depending on whether you or the
compiler handles the dispatching.
Well, I think "overloading" and "Python" may not even belong in the
same sentence, actually. "Overloading" is used in C++, Java and C# to
describe a single method name with multiple signatures. It is not
really possible to implement such a thing in Python, which just binds
methods to names, and duplicate definitions of methodX just replace
the former with the latter.

But from the standpoint of the caller, calls to methodX() with various
numbers and types of arguments looks just the same as it does in Java
or C# with method overloading, and could reasonably be thought of as
such - what does the caller care how methodX handles these various
calls, whether with 1 hyper-adaptive method implementation or a dozen
type-specific ones?

I've had this discussion before, but I personally tend to reserve the
term "polymorphism" for instance-level behavior, such as when a
collection of instances that all derive from a common base class have
overridden method definitions. The typical example is a list of
Shapes, each implementing its own draw() method, so that they
polymorphically do their subclass-appropriate draw behavior. Or for a
Strategy pattern implementation (one of my favorite), where derived
strategy classes implement a base interface with their separate
behaviors, and each is accessed through the interface definition.

The beauty of Python's duck-typing is that this same kind of
polymorphism can be achieved without the burden of class inheritance
hierarchies. As long as the instances referenced all implement
methodX(), Python is happy. If I'm desperate, I could even
dynamically attach a do-nothing or default version of such a method if
it were not already defined for an instance. Try *that* in C++
(without a horrifying haystack of angle brackets)!

I have heard "overloading" referred to as "method polymorphism", but I
think this is just a dilution of the "polymorphism" term, with no
additional knowledge transfer gained.

-- Paul
Feb 15 '07 #7

P: n/a
On 14 Feb 2007 20:54:31 -0800, placid <Bu****@gmail.comwrote:
class Test:
def __init__(self):
pass

def puts(self, str):
print str

def puts(self, str,str2):
print str,str2
you might look into the overloading module and its decorator. source
is in the sandbox:

http://svn.python.org/view/sandbox/t...overloading.py

using it, you could re-write your example as:

#
from overloading import overloaded

class Test(object):

@overloaded
def puts(self, S):
print S

@puts.register(object, str, str)
def puts_X(self, S, S2):
print S, S2

two things to note. first, i changed your class to derive from
object. I don't know if that's required, but i suspect it is.

second, i changed your argument names. the argument names in your
example shadow built-in names. you shouldn't do that in any case, but
it could become especially confusing using the overloaded decorator,
which relies on argument type to select the correct method.
Feb 15 '07 #8

P: n/a
On 15 fév, 09:32, "Troy Melhase" <troy.melh...@gmail.comwrote:
On 14 Feb 2007 20:54:31 -0800, placid <Bul...@gmail.comwrote:
class Test:
def __init__(self):
pass
def puts(self, str):
print str
def puts(self, str,str2):
print str,str2

you might look into the overloading module and its decorator. source
is in the sandbox:

http://svn.python.org/view/sandbox/t...overloading.py
Or have a look at Philip Eby's dispatch package, which is kind of
overloading on steroids...

Feb 15 '07 #9

P: n/a
On 2007-02-15, placid <Bu****@gmail.comwrote:
Is it possible to be able to do the following in Python?
class Test:
def __init__(self):
pass
def puts(self, str):
print str
def puts(self, str,str2):
print str,str2
if __name__ == "__main__":
t = Test()
t.puts("hi")
t.puts("hi","hello")

You tell us: what happened when you tried it?

Well, when i run it i get this error "puts() takes exactly 3 arguments
(2 given)" which means that the second a time i try to define the
puts() method "overwrites" the first one
Correct. That means it's not possible to do what you wrote.
>And then what happens when you do this?

class Test:
def __init__(self):
pass

def puts(self, *args):
print ' '.join(args)

if __name__ == "__main__":
t = Test()
t.puts("hi")
t.puts("hi","hello")

but this isn't overloading.
No, it isn't. [You can't overload methods in Python. Was that
your question?] It is, however, the way one does what you
appear to be trying to do.

--
Grant Edwards grante Yow! If I am elected no
at one will ever have to do
visi.com their laundry again!
Feb 15 '07 #10

P: n/a
On 2007-02-15, Steven D'Aprano <st***@REMOVEME.cybersource.com.auwrote:
>def multiAccept( argOfVariousTypes ):
if isinstance(argOfVariousTypes,int):
# treat like an int
elif isinstance(argOfVariousTypes,float):
# treat like a float
elif isinstance(argOfVariousTypes,(list,tuple)):
# treat like a container

Is that really called "overloading"? I've never (knowingly)
come across the term being used in that context before. I've
always known that as "multiple dispatch" or "polymorphism",
depending on whether you or the compiler handles the
dispatching.
It's due to vague terminology that we're using.

What the OP wanted to know about was static polymorphism of names
based on function signatures, often refered to informally in the
context of C++ as "function overloading", though it's really
"identifier overloading where identifier refers to a function or
member function".

What Python provides is dynamic polymorphism of names with
single-dispatch.

I think. ;-)

--
Neil Cerutti
Feb 15 '07 #11

P: n/a
On Feb 16, 3:37 am, Neil Cerutti <horp...@yahoo.comwrote:
On 2007-02-15, Steven D'Aprano <s...@REMOVEME.cybersource.com.auwrote:
def multiAccept( argOfVariousTypes ):
if isinstance(argOfVariousTypes,int):
# treat like an int
elif isinstance(argOfVariousTypes,float):
# treat like a float
elif isinstance(argOfVariousTypes,(list,tuple)):
# treat like a container
Is that really called "overloading"? I've never (knowingly)
come across the term being used in that context before. I've
always known that as "multiple dispatch" or "polymorphism",
depending on whether you or the compiler handles the
dispatching.

It's due to vague terminology that we're using.

What the OP wanted to know about was static polymorphism of names
based on function signatures, often refered to informally in the
context of C++ as "function overloading", though it's really
"identifier overloading where identifier refers to a function or
member function".
This what i was asking.
>
What Python provides is dynamic polymorphism of names with
single-dispatch.

I think. ;-)

--
Neil Cerutti
Thank you all for the information.
Feb 15 '07 #12

This discussion thread is closed

Replies have been disabled for this discussion.