Google Gruppi non supporta piĂą i nuovi post o le nuove iscrizioni Usenet. I contenuti storici continuano a essere visibili.

function overloading

0 visualizzazioni
Passa al primo messaggio da leggere

Mirko Koenig

da leggere,
24 mag 2003, 11:33:1024/05/03
a
Hi

I serached around the web and some tutorials but i can't finds any
documentation about function overloading in python.

I want to have 3 functions:
def setPos( x, y ):

def setPos( pos ):

def setPos( object ):

( pos and object are classes i wrote )

I wrote all these functions but only the one that is the least in the
code i used.
So i can't call setPos( 1,2 ), because def setPos( object ) is used.

Is it not possible in python to overload fucntion with the same name?
How do you do it?

Mirko Koenig

Martin v. Löwis

da leggere,
24 mag 2003, 11:55:3324/05/03
a
Mirko Koenig <koe...@v-i-t.de> writes:

> I serached around the web and some tutorials but i can't finds any
> documentation about function overloading in python.

Because there just is no function overloading in Python.

> I want to have 3 functions:

However, you cannot get them:

> def setPos( x, y ):
>
> def setPos( pos ):
>
> def setPos( object ):

A def statement is roughly executed like this:
1. Compile the body of the function.
2. Build a function object __f
3. Assign it:
setPos = _f

So the second definition just overwrites the earlier one.

> Is it not possible in python to overload fucntion with the same name?
> How do you do it?

No, it's not possible. I strongly recommend that you find different
function names. If you absolutely must have all three functions with
the same name, you can write the function like this

def setPos(*args):
assert 0 < len(args) < 3
if len(args) == 2:
x,y = args
...
elif args[0] is a position:
pos = args[0]
...
else:
object = args[0]
...

HTH,
Martin

Alex Martelli

da leggere,
24 mag 2003, 11:46:4624/05/03
a
Mirko Koenig wrote:

> Hi
>
> I serached around the web and some tutorials but i can't finds any
> documentation about function overloading in python.

That may be because there is no such thing.


> I want to have 3 functions:
> def setPos( x, y ):
>
> def setPos( pos ):
>
> def setPos( object ):

You cannot have three different objects (for example, three different
functions) corresponding to the same name in the same scope. One name,
one scope, one object.

> Is it not possible in python to overload fucntion with the same name?

Exactly! Whenever you bind a name X to an object Y -- whether that
happens with a def statement, an assignment, or in other ways yet -- any
previous binding to the same name X in the same scope is simply forgotten.

> How do you do it?

We don't (bind several different objects to the same name in a given
scope). If you're keen on being able to call setPos(x,y) as well as
setPos(pos) there are several ways you can achieve this effect -- e.g.

def setPos(x,y):
"whatever"

setPos_2args = setPos

def setPos(pos):
"whatever"

setPos_postype = setPos

def setPos(another):
"whatever"

setPos_anyother = setPos

def setPos(*args):
if len(args)==2: return setPos_2args(*args)
if len(args)>1: raise TypeError
if type(args[0]) == postype: return setPos_postype(*args)
return setPos_anyother(*args)


Of course, it's quite unnatural and stilted to program in this way,
as is typical of such efforts to use the programming style appropriate
to language X while actually programming in very different language Y.
If you learn to program in Y's own style, you will be more productive
and generally happier.


Alex

Jay O'Connor

da leggere,
24 mag 2003, 12:07:5124/05/03
a
On Sat, 24 May 2003 17:33:10 +0200, Mirko Koenig <koe...@v-i-t.de>
wrote:


>Is it not possible in python to overload fucntion with the same name?
>How do you do it?

Function overloading tends not to work in dynamically bound languages.
In C you can have

int myFunc (int a) {};
int myFunc (char* a) {};

and the compiler can tell by the types involved which function to
call.

languages that don't statically bind variables to a given type don't
do so well with this:

def myFunc (myInt):
pass

def myFunc (myString):
pass

Since the function definiftion has no type information, the compiler
could not resolve which function to call

In Pyhon's case, the functions are kept in a dictionary keyed of the
function name (iirc) so having two functions with the same name but
different parameter lists doesn't work either. When the compiler
compiles the second function, it replaces the first in the dictionary,
which is why your last function is the only one that gets called.

You are better off either

a) having functions with slightly different names or
b) using polymorphism to allow one function to handle different types,
cleanly.


Take care,
Jay

David Mertz

da leggere,
24 mag 2003, 13:13:0624/05/03
a
|Mirko Koenig wrote:
|> I want to have 3 functions:
|> def setPos( x, y ):
|> def setPos( pos ):
|> def setPos( object ):

Alex Martelli <ale...@yahoo.com> wrote previously:


|You cannot have three different objects (for example, three different
|functions) corresponding to the same name in the same scope. One name,
|one scope, one object.

Readers of this thread might be interested in my article and library for
multiple dispatch in Python:

http://www-106.ibm.com/developerworks/linux/library/l-pydisp.html

While a given name is still only defined once, it is possible to control
the code called based on the type and number of its arguments.

Take it or leave it... it may not be the best approach to Koenig's
concern. But maybe something to consider.

--
_/_/_/ THIS MESSAGE WAS BROUGHT TO YOU BY: Postmodern Enterprises _/_/_/
_/_/ ~~~~~~~~~~~~~~~~~~~~[me...@gnosis.cx]~~~~~~~~~~~~~~~~~~~~~ _/_/
_/_/ The opinions expressed here must be those of my employer... _/_/
_/_/_/_/_/_/_/_/_/_/ Surely you don't think that *I* believe them! _/_/


laotseu

da leggere,
24 mag 2003, 19:28:2524/05/03
a
Jay O'Connor wrote:
> On Sat, 24 May 2003 17:33:10 +0200, Mirko Koenig <koe...@v-i-t.de>
> wrote:
>
>
>
>>Is it not possible in python to overload fucntion with the same name?
>>How do you do it?
>
>
> Function overloading tends not to work in dynamically bound languages.

<HS>
Have a look on multidispatch (generic) methods in CLOS, which is a
dynamically bound language. It works, and it's really some kind of
function overloading !-)

> In C you can have
>
> int myFunc (int a) {};
> int myFunc (char* a) {};
>
> and the compiler can tell by the types involved which function to
> call.

No you can't. Try to compile this and you'll get two errors :
- conflicting types for 'myFunc'
- previous declaration of 'myFunc'

Your example would work in C++, but C and C++ are two different languages...
</HS>

Laotseu

Jay O'Connor

da leggere,
24 mag 2003, 18:38:3724/05/03
a
On Sat, 24 May 2003 23:28:25 +0000, laotseu
<bde...@removethis.free.fr> wrote:


>> In C you can have
>>
>> int myFunc (int a) {};
>> int myFunc (char* a) {};
>>
>> and the compiler can tell by the types involved which function to
>> call.
>
>No you can't. Try to compile this and you'll get two errors :
>- conflicting types for 'myFunc'
>- previous declaration of 'myFunc'
>
>Your example would work in C++, but C and C++ are two different languages...
></HS>

Fair enough. I knew the concept that I was shooting for but was a bit
rusty to provide a workable examle.

Take care,
Jay

Jere Kahanpaa

da leggere,
3 lug 2003, 02:33:3803/07/03
a
Hi.

Mirko Koenig <koe...@v-i-t.de> wrote:
> I serached around the web and some tutorials but i can't finds any
> documentation about function overloading in python.

> I want to have 3 functions:
> def setPos( x, y ):
> def setPos( pos ):
> def setPos( object ):
> ( pos and object are classes i wrote )

The normal Pythonic way is probably as follows:

def setPos(position):
"""
Set Position.

The 'position' argument should be one of
* a tuple of coordinates (x,y)
* a instance of class Pos
* a instance of class Object
"""

if type(positions) is types.TupleType or type(positions) is types.ListType:
x,y = positions
...
else if:
... identify object type and process

Jere
--
It's hard to think outside the box when you ARE the box.
- unknown, alt.religion.kibology

Karl Scalet

da leggere,
3 lug 2003, 04:35:3203/07/03
a
Alex Martelli schrieb:

>
> We don't (bind several different objects to the same name in a given
> scope). If you're keen on being able to call setPos(x,y) as well as
> setPos(pos) there are several ways you can achieve this effect -- e.g.
>
> def setPos(x,y):
> "whatever"
>
> setPos_2args = setPos
>

what is the benefit of this "renaming" over just
name the dispatch-function setPos_2args directly:

def setPos_2args(x,y):
"whatever"

> ....


>
> def setPos(*args):
> if len(args)==2: return setPos_2args(*args)
> if len(args)>1: raise TypeError
> if type(args[0]) == postype: return setPos_postype(*args)
> return setPos_anyother(*args)

> ...

Karl

Cliff Wells

da leggere,
3 lug 2003, 18:00:5003/07/03
a
On Wed, 2003-07-02 at 23:33, Jere Kahanpaa wrote:
> Hi.
>
> Mirko Koenig <koe...@v-i-t.de> wrote:
> > I serached around the web and some tutorials but i can't finds any
> > documentation about function overloading in python.
>
> > I want to have 3 functions:
> > def setPos( x, y ):
> > def setPos( pos ):
> > def setPos( object ):
> > ( pos and object are classes i wrote )
>
> The normal Pythonic way is probably as follows:
>
> def setPos(position):
> """
> Set Position.
>
> The 'position' argument should be one of
> * a tuple of coordinates (x,y)
> * a instance of class Pos
> * a instance of class Object
> """
>
> if type(positions) is types.TupleType or type(positions) is types.ListType:
> x,y = positions
> ...
> else if:
> ... identify object type and process


Or you could implement something like this, if think you "need"
overloading so badly that the horrific overhead added to each function
call is tolerable:

class overload(object):
def __init__(self, *args):
self._funcs = {}
for f, p in args:
self._funcs[tuple([type(a) for a in p])] = f

def __call__(self, *args):
f = self._funcs[tuple([type(a) for a in args])]
return f(*args)

def f_noargs():
print "noargs"

def f_int(a, b):
print "ints", a, b

def f_str(a, b):
print "str", a, b

def f_strint(a, b):
print "strint", a, b

f = overload(
[ f_noargs, () ],
[ f_int, (int(), int()) ],
[ f_str, (str(), str()) ],
[ f_strint, (str(), int()) ]
)

f()
f(1, 2)
f('a', 'b')
f('c', 3)


> It's hard to think outside the box when you ARE the box.

Or if the box is full of Chicken McNuggets. Mmmm.

--
Cliff Wells, Software Engineer
Logiplex Corporation (www.logiplex.net)
(503) 978-6726 (800) 735-0555


0 nuovi messaggi