Method acting on arguements passed

  • Thread starter Panos Laganakos
  • Start date
P

Panos Laganakos

I want a class method to take action depending on the type of the
arguement passed to it.

ie:
getBook(id) # get the book by ID
getBook(name) # get the book by name
....

Other languages use the term function/method overloading to cope with
this. And when I googled about it seems that GvR is testing it for 3.0
inclusion or so.

I was thinking of right after the function declaration check for the
parameter passed by isinstance() or type() and use if..elif..else to
act.

Is this the pythonic way/best practice to apply here?
 
D

Diez B. Roggisch

Panos said:
I want a class method to take action depending on the type of the
arguement passed to it.

ie:
getBook(id) # get the book by ID
getBook(name) # get the book by name
...

Other languages use the term function/method overloading to cope with
this. And when I googled about it seems that GvR is testing it for 3.0
inclusion or so.

I was thinking of right after the function declaration check for the
parameter passed by isinstance() or type() and use if..elif..else to
act.

Is this the pythonic way/best practice to apply here?

google for gnosis multimethods for a clean approach.


Diez
 
D

Duncan Booth

Panos said:
I want a class method to take action depending on the type of the
arguement passed to it.

ie:
getBook(id) # get the book by ID
getBook(name) # get the book by name
...

Other languages use the term function/method overloading to cope with
this. And when I googled about it seems that GvR is testing it for 3.0
inclusion or so.

I was thinking of right after the function declaration check for the
parameter passed by isinstance() or type() and use if..elif..else to
act.

Is this the pythonic way/best practice to apply here?
I think the most Pythonic way is probably to have separate methods. You
presumably know at the point when you are calling getBook whether you have
an id or a name. So be explicit:

getBookById(id)
getBookByName(name)

This has the advantage that id and name could both be strings and the code
will still do the right thing. No amount of function overloading will
resolve arguments which have the same type but mean different things.

Another reasonable way to go is to use keyword arguments:

getBook(id=id)
getBook(name=name)

which keeps down the number of different methods but could be confusing as
you have mutually exclusive keyword arguments.

Another option you might have here, if getBook does a lookup in a
dictionary, or database query, is simply to index the books by both id and
name. Then the definition might be:

def getBook(self, idorname):
return self._books[idorname]

and there is still no typechecking.

If you do feel you need typechecking, consider pulling it out into a
separate method so you are actually testing for the meaning of the
parameter rather than explicitly testing its type everywhere:

def getBook(self, idorname):
if self.isvalidid(idorname):
....
elif self.isvalidname(idorname):
....
else:
raise Oops()
 
B

bruno at modulix

Panos said:
I want a class method to take action depending on the type of the
arguement passed to it.

ie:
getBook(id) # get the book by ID
getBook(name) # get the book by name
...

Other languages use the term function/method overloading to cope with
this. And when I googled about it seems that GvR is testing it for 3.0
inclusion or so.

I was thinking of right after the function declaration check for the
parameter passed by isinstance() or type() and use if..elif..else to
act.

Is this the pythonic way/best practice to apply here?

For simple case and if there's no need for extensibility, this is
usually quite enough - even if somewhat ugly. If the code for each case
is really different, I'd split the whole thing into three separate
methods : getBookById, getBookByName, and getBook that only do the
dispatch.

Else - and depending on the context, needs, specs and whatnot, I'd look
either at the visitor pattern (or any custom double-dispatch) or at an
existing multimethod implementation (like David Mertz's multimethod or
Philip Eby's protocol.dispatch).

My 2 cents
 
A

Andrew Gwozdziewycz

I want a class method to take action depending on the type of the
arguement passed to it.

ie:
getBook(id) # get the book by ID
getBook(name) # get the book by name

Keyword arguments are going to be the best solution, but you'll still
have to do checks like in this example which uses a generic keyword
and determines it's type..

def getBook(arg):
id = None
name = None
try:
id = int(arg)
# use the id here
except ValueError:
name = arg
# use name here

Now, if you were to use named arguments:
def getBook(id=None, name=None):
if id:
# do whatever for id
elif name:
# do whatever for name here

They are nearly identical.
---
Andrew Gwozdziewycz
(e-mail address removed)
http://www.23excuses.com
http://ihadagreatview.org
http://and.rovir.us
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,294
Messages
2,571,511
Members
48,207
Latest member
KazukoCape

Latest Threads

Top