Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Method overloading?

Reply
Thread Tools

Method overloading?

 
 
placid
Guest
Posts: n/a
 
      02-15-2007
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

 
Reply With Quote
 
 
 
 
Grant Edwards
Guest
Posts: n/a
 
      02-15-2007
On 2007-02-15, placid <> wrote:

> 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!
 
Reply With Quote
 
 
 
 
placid
Guest
Posts: n/a
 
      02-15-2007
On Feb 15, 4:04 pm, Grant Edwards <gra...@visi.com> wrote:
> On 2007-02-15, placid <Bul...@gmail.com> wrote:
>
>
>
> > 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!



 
Reply With Quote
 
Paul McGuire
Guest
Posts: n/a
 
      02-15-2007
On Feb 14, 10:54 pm, "placid" <Bul...@gmail.com> wrote:
> 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


 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      02-15-2007
On Wed, 14 Feb 2007 21:12:39 -0800, placid wrote:

> On Feb 15, 4:04 pm, Grant Edwards <gra...@visi.com> wrote:
>> On 2007-02-15, placid <Bul...@gmail.com> wrote:
>>
>>
>>
>> > 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

 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      02-15-2007
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

 
Reply With Quote
 
Paul McGuire
Guest
Posts: n/a
 
      02-15-2007
On Feb 15, 12:23 am, Steven D'Aprano
<s...@REMOVEME.cybersource.com.au> wrote:
> 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


 
Reply With Quote
 
Troy Melhase
Guest
Posts: n/a
 
      02-15-2007
On 14 Feb 2007 20:54:31 -0800, placid <> wrote:
> 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.
 
Reply With Quote
 
bruno.desthuilliers@gmail.com
Guest
Posts: n/a
 
      02-15-2007
On 15 fév, 09:32, "Troy Melhase" <troy.melh...@gmail.com> wrote:
> On 14 Feb 2007 20:54:31 -0800, placid <Bul...@gmail.com> wrote:
>
> > 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...

 
Reply With Quote
 
Grant Edwards
Guest
Posts: n/a
 
      02-15-2007
On 2007-02-15, placid <> wrote:

>> > 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!
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
method def in method vs method def in block Kyung won Cheon Ruby 0 11-21-2008 08:48 AM
invoke a method by reflection£¬the method's parameters can not be ArrayList? jerry051 ASP .Net 2 08-02-2005 10:35 AM
BC30289: Statement cannot appear within a method body. End of method assumed. Carlos Oliveira ASP .Net 0 08-19-2004 07:51 PM
Difference between Delete method and RemoveRow method CW ASP .Net 0 04-01-2004 01:07 AM
ASP.NET: BC30289: Statement cannot appear within a method body. End of method assumed. Mike Wilmot ASP .Net 0 12-15-2003 07:49 PM



Advertisments