472,965 Members | 2,028 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,965 software developers and data experts.

Python's idiom for function overloads


Hello,

Since Python doesn't have static typing, how is the same result as traditional
function overloads results in acheived? With function overloads the
"selection of code path depending on data type" is transparent and automatic
since the typing system figure out what goes to what.

But in Python, when one wants to be able to pass different data types into a
single "entry point" for functionality, how is that best done? To in a
function do an if statement with the type() function?
Cheers,

Frans

Jul 18 '05 #1
12 1803
Hi Frans,
Since Python doesn't have static typing, how is the same result as traditional
function overloads results in acheived?
With dynamic typing obviously. :-)

You can not reproduce the C++ overload idiom but you can get something
close with manual type testing.
To in a
function do an if statement with the type() function?


I am not aware of any other method.

def a( arg1 ):
if type(arg1) == types.IntType: return aWithInt(arg1)
if type(arg1) == types.ListType: return aWithList(arg1)
...

As you see, it is a bit tedious sometimes.

If you want to juggle with completely different signatures, you have to
play with variable argument lists. But I have found in my experience
that the best way to get close to the C++ idiom, while improving
readbility, is by using kwparams:

def a(**kwparams):
if kwparams.has_key('argInt'): aWithInt(kwparams['argInt'])
if kwparams.has_key('argString'): aWithString(kwparams['argString'])

The parsing code is the same, but the intent of the user is better
expressed and you can catch misuse in a better fashion:
if kwparams.has_key('argInt') and kwparams.has_key('argString'):
print "You stupid moron, a can be used only with string or int but not
both at the same time!"
sys.exit(1)

The example speaks better in a real case. Imagine a processPixmap function:
processPixmap( pixmap=QPixmap(...) )
processPixmap( filename='my_pixmap.png' )
processPixmap( buffer=my_pixmap_string_content )

It works actually even better with multiple arguments.

regards,

Philippe
Jul 18 '05 #2
Frans Englich wrote:
But in Python, when one wants to be able to pass different data types into a
single "entry point" for functionality, how is that best done? To in a
function do an if statement with the type() function?


It often depends a lot on the specific use case... Do you have a
particular example in mind?

Steve
Jul 18 '05 #3
> > Since Python doesn't have static typing, how is the same result as
traditional
function overloads results in acheived?
The more you program in Python, the less you are missing it.

As Philippe already said, use objects that support the protocol or decide
what to do with it after having checked its type. I do that, if I have to,
like so:

def doIt(arg):
if type(arg) == type([]):
map(doIt, arg)
else:
# Do it on a scalar type
# ...
return result

HTH
Franz GEIGER
"Philippe Fremy" <ph**@freehackers.org> schrieb im Newsbeitrag
news:41**********************@news.free.fr...
Hi Frans,
Since Python doesn't have static typing, how is the same result as
traditional function overloads results in acheived?


With dynamic typing obviously. :-)

You can not reproduce the C++ overload idiom but you can get something
close with manual type testing.
> To in a
> function do an if statement with the type() function?


I am not aware of any other method.

def a( arg1 ):
if type(arg1) == types.IntType: return aWithInt(arg1)
if type(arg1) == types.ListType: return aWithList(arg1)
...

As you see, it is a bit tedious sometimes.

If you want to juggle with completely different signatures, you have to
play with variable argument lists. But I have found in my experience
that the best way to get close to the C++ idiom, while improving
readbility, is by using kwparams:

def a(**kwparams):
if kwparams.has_key('argInt'): aWithInt(kwparams['argInt'])
if kwparams.has_key('argString'): aWithString(kwparams['argString'])

The parsing code is the same, but the intent of the user is better
expressed and you can catch misuse in a better fashion:
if kwparams.has_key('argInt') and kwparams.has_key('argString'):
print "You stupid moron, a can be used only with string or int but not
both at the same time!"
sys.exit(1)

The example speaks better in a real case. Imagine a processPixmap

function: processPixmap( pixmap=QPixmap(...) )
processPixmap( filename='my_pixmap.png' )
processPixmap( buffer=my_pixmap_string_content )

It works actually even better with multiple arguments.

regards,

Philippe

Jul 18 '05 #4
Philippe Fremy <ph**@freehackers.org> writes:
Hi Frans,
Since Python doesn't have static typing, how is the same result as
traditional function overloads results in acheived?

With dynamic typing obviously. :-)

You can not reproduce the C++ overload idiom


Of course you can. Use a multimethod of some sort.

The canonical answer to the OQ, of course, includes things like
"Consider whether you really want/need to do this" and "duck typing".

Frequently, in Python, code which checks for types, rather than
checking for features, ends up being excessively restrictive and
insufficiently general.
Jul 18 '05 #5
"F. GEIGER" <f.******@vol.at> writes:
As Philippe already said, use objects that support the protocol or decide
what to do with it after having checked its type. I do that, if I have to,
like so:

1 def doIt(arg):
2 if type(arg) == type([]):
3 map(doIt, arg)
4 else:
5 # Do it on a scalar type
6 # ...
7 return result


Now, consider that line 3 would execute very happily if the type of
arg were

1) list,
2) str,
3) tuple,
4) dict,
5) file,
6) any other built-in iterable or sequence,
7) any useer-defined iterable or sequence,
8) a subclass of any of the above,
9) god knows what else ...

.... yet in line 2 you have ensured that the whole function will not
work properly for any of the listed types other than the first.

You could make the code much more general by doing it like this:

try:
map(doIt, arg)
except TypeError:
...
The important thing to note is that the actual types of Python objects
are usually not very interesting or important at all. What is much
more important is what the object is able to do: what messages it
understands, what protocols it supports.

Hiding some code behind a type-check, in Python, is quite frequently
the wrong thing to do.
Jul 18 '05 #6
Frequently, in Python, code which checks for types, rather than
checking for features, ends up being excessively restrictive and
insufficiently general.


That's true, but checking for the exact features that are going to be
needed by your code is usually quite complicated and painful to
maintain. At the beginning, you need only a sequence. In the end, you
need a mutable sequence that supports slicing, so you could go by
requiring a list as well.

Enforcing types also brings the benefit that the program is more
deterministic. In my experience, there is a lot more benefits to have an
object whose type is clearly identified than to have function that
accepts generic objects.

I would go as far as saying that variables should have immutable types.
It is more restricting that what python provides currently, but leads to
clearer programming practice: the intent of the developer shows up in
the type he uses.

Of course, with languages such as OCaml, you get both of it: liberal
typing with enforced consistency.

While Python's dynamic typing liberty is enjoyable, I think it harms
when you start to work on big projects. It prevents you to put many
safety assumptions which might bite you back.

regards,

Philippe
Jul 18 '05 #7
Philippe Fremy <ph**@freehackers.org> writes:
Enforcing types also brings the benefit that the program is more
deterministic. In my experience, there is a lot more benefits to have
an object whose type is clearly identified than to have function that
accepts generic objects.
I would go as far as saying that variables should have immutable
types.
If you really believe this, then I would go as far as saying that you
would be happier in a language other than Python.
It is more restricting that what python provides currently, but
leads to clearer programming practice: the intent of the developer
shows up in the type he uses.


Not in my opinion or experience.

To each his own, and vice versa.
Jul 18 '05 #8
Le Tue, 01 Feb 2005 12:10:47 +0100, Philippe Fremy a écrit :
Frequently, in Python, code which checks for types, rather than
checking for features, ends up being excessively restrictive and
insufficiently general.

snip
Enforcing types also brings the benefit that the program is more
deterministic. In my experience, there is a lot more benefits to have an
object whose type is clearly identified than to have function that
accepts generic objects. If you insist to always have only clearly identified types of variables
you will use the Hungarian notation :
bool bIsDir = blah
const char *lpszMessage = "It's a directory";
I would go as far as saying that variables should have immutable types.
It is more restricting that what python provides currently, but leads to
clearer programming practice: the intent of the developer shows up in
the type he uses. clearer programming practice which goes with unreadable code ?

While Python's dynamic typing liberty is enjoyable, I think it harms
when you start to work on big projects. It prevents you to put many
safety assumptions which might bite you back. Python is strongly typed (at run-time). You can get a traceback sure but
it is rather difficult to get unreliable results.
regards,

Philippe

Jul 18 '05 #9
On Tuesday 01 February 2005 05:02, Steven Bethard wrote:
Frans Englich wrote:
But in Python, when one wants to be able to pass different data types
into a single "entry point" for functionality, how is that best done? To
in a function do an if statement with the type() function?


It often depends a lot on the specific use case... Do you have a
particular example in mind?


I did have a specific scenario, but it blurred into a general wondering about
typing. I think my problem was, and still is, that I don't think in Python
terms but try to force other idioms. Thinking in static typic terms when
Python goes in the opposite direction clearly shows friction is created.
The replies were interesting,

Frans
Jul 18 '05 #10
On Tue, 1 Feb 2005 04:17:10 +0000, Frans Englich <fr***********@telia.com> wrote:
....
But in Python, when one wants to be able to pass different data types into a
single "entry point" for functionality, how is that best done? To in a
function do an if statement with the type() function?


Have a look at this older thread on this subject:

Subject: Re: Does python support multi prototype.
Message-ID: <TZ********************@powergate.ca>

/Jorgen

--
// Jorgen Grahn <jgrahn@ Ph'nglui mglw'nafh Cthulhu
\X/ algonet.se> R'lyeh wgah'nagl fhtagn!
Jul 18 '05 #11
Philippe Fremy <ph**@freehackers.org> writes:
You can not reproduce the C++ overload idiom but you can get something
close with manual type testing.
> To in a
> function do an if statement with the type() function?


I am not aware of any other method.

def a( arg1 ):
if type(arg1) == types.IntType: return aWithInt(arg1)
if type(arg1) == types.ListType: return aWithList(arg1)
...


Or:

def a_overloader (arg1):
return my_typed_a_func_dict[type (arg1)] (arg1)

Next I'd put my hands in automating the creation of these wrappers and
the my_typed_a_func_dict map based on my implementation written so
far. Then I'd think of parameterizing on any arbitrary destructuring
of arguments like def foo ((a,b), c) and also on classes to which
instance methods are bound to. At this point, a preprocessor might be
handy to avoid seeing all the internals after which things would
probably start looking sick enough to either switch languages or
thinking of the right problem first and then come up with a pythonic
solution to _that_.
br,
S
Jul 18 '05 #12
On Wed, 02 Feb 2005 14:45:35 -0800 (PST), Simo Melenius
<fi****************@iki.fi-spam> wrote:
Philippe Fremy <ph**@freehackers.org> writes:
You can not reproduce the C++ overload idiom but you can get something
close with manual type testing.
> To in a
> function do an if statement with the type() function?


I am not aware of any other method.

def a( arg1 ):
if type(arg1) == types.IntType: return aWithInt(arg1)
if type(arg1) == types.ListType: return aWithList(arg1)
...


Or:

def a_overloader (arg1):
return my_typed_a_func_dict[type (arg1)] (arg1)

Next I'd put my hands in automating the creation of these wrappers and
the my_typed_a_func_dict map based on my implementation written so
far. Then I'd think of parameterizing on any arbitrary destructuring
of arguments like def foo ((a,b), c) and also on classes to which
instance methods are bound to. At this point, a preprocessor might be
handy to avoid seeing all the internals after which things would
probably start looking sick enough to either switch languages or
thinking of the right problem first and then come up with a pythonic
solution to _that_.


Pah.

Use a decorator.

Code is available here:
Jack Diederich posted a good multimethod snippet here, in response to
my own clumsy effort.

http://groups-beta.google.com/group/...50153e3fb84862
http://tinyurl.com/4awat

type(arg1) == types.IntType
def multi_type(t):
return multi(lambda x:type(x) == t)

@multi_type(types.IntType)
def foo(x):
return someOperationOnInt(x)

@multi_type(types.FloatType)
def foo(x):
return someOperationOnFloat(x)

Regards,
Stephen Thorne.

"Just because it is possible doesn't make a good idea *wink*",
-Jack Diederich, Aug 2004
Jul 18 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

226
by: Stephen C. Waterbury | last post by:
This seems like it ought to work, according to the description of reduce(), but it doesn't. Is this a bug, or am I missing something? Python 2.3.2 (#1, Oct 20 2003, 01:04:35) on linux2 Type...
49
by: Ville Vainio | last post by:
I don't know if you have seen this before, but here goes: http://text.userlinux.com/white_paper.html There is a jab at Python, though, mentioning that Ruby is more "refined". -- Ville...
68
by: Lad | last post by:
Is anyone capable of providing Python advantages over PHP if there are any? Cheers, L.
9
by: jezonthenet | last post by:
I started using Python a couple of days ago - here are a few questions: * Doesn't the __main__() method automatically execute when I run my python program? * Only when I do an import of my...
30
by: Ivan Reborin | last post by:
Hello everyone, I was wondering if anyone here has a moment of time to help me with 2 things that have been bugging me. 1. Multi dimensional arrays - how do you load them in python For...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
2
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.