Method overloading?
Paul McGuire
ptmcg at austin.rr.com
Thu Feb 15 00:58:35 EST 2007
On Feb 14, 10:54 pm, "placid" <Bul... at 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
More information about the Python-list
mailing list