polymorphism w/out signatures?

P

pugnatio2

What's the standard way to implement polymorphic behavior in a python
method, given that method arguments can't declare their types as
they're being passed in, and method definitions don't have signatures?

For instance, if I wanted to write a method that auto-detected whether
it was being passed a string or a tuple/list, how would I do so
without using type() to identify the parameter's type? Using type() is
deprecated in the documentation I've read.

Thanks in advance.
 
R

Roy Smith

What's the standard way to implement polymorphic behavior in a python
method, given that method arguments can't declare their types as
they're being passed in, and method definitions don't have signatures?

For instance, if I wanted to write a method that auto-detected whether
it was being passed a string or a tuple/list, how would I do so
without using type() to identify the parameter's type? Using type() is
deprecated in the documentation I've read.

Thanks in advance.

For the most part, the kind of polymorphism you see in staticly typed
languages like C++ and Java just isn't necessary in Python.

Between dynamic typing (i.e. you can take the str() of anything without
knowing what type it is) and keyword arguments, there's very little
reason to have to know what type an argument is.

The most common reason is the example you gave, where you want a
function which will operate on either an item, or a bunch of items. You
might want to be able to say:

nuke ("Perl")

to get rid of everybody's least favorite language, and also be able to
pass in a bunch of them:

nuke (("C++", "Java", "Perl"))

to get rid of all three at once. If you really wanted to do that, you
could define nuke something like:

def nuke (lang):
if isinstance (lang, types.TupleType):
for oneLanguage in lang:
nuke (oneLanguage)
else:
whatever

In general, however, I try to stay away from stuff like that.
 
L

Larry Bates

I use type() quite a lot. I poked around and couldn't
find where it was being deprecated. I did see that
types module is slated for deprecation. Maybe I
overlooked it?

I use:

class foo:
_stringtype=type('')
_tupletype=type(())
_listtype=type([])

def __init__(self, variable):
if type(variable) == _stringtype:
self.variable=variable # check for string type
if type(variable) in (_listtype, tupletype):
self.variable=str(variable) # check for list/tuple
.
.
.

Seems to work well. You might also want to look at
isinstance() function

Larry Bates
Syscon, Inc.
 
D

Donn Cave

What's the standard way to implement polymorphic behavior in a python
method, given that method arguments can't declare their types as
they're being passed in, and method definitions don't have signatures?

For instance, if I wanted to write a method that auto-detected whether
it was being passed a string or a tuple/list, how would I do so
without using type() to identify the parameter's type? Using type() is
deprecated in the documentation I've read.

type() does what you want to do. It's not so much that
the function is deprecated, rather the idea behind wanting
to use it in the first place.

A string is a kind of sequence, as are lists and tuples.
If you really want to deal with a string as a variation on
that theme, but there are differences that you have to take
into account, then maybe someone can suggest an approach if
you can describe the issue.

On the other hand, if you want to support a string as an single
value instead of a list or tuple of values, then you're not
really talking about polymorphism here anyway. When a function
decides to support various unrelated types for a particular
parameter, I don't know what you call that, but it isn't
polymorphism in any useful sense. It has been done, it's
up to you whether you want to do it, but personally I think
it's bad news because it's confusing and difficult to do right.
A misguided convenience.

Polymorphism is about a function supporting a range of objects
that conform to a certain specification (in Python that's an
implicit specification.) Like a function written with a file
object in mind can also support a cStringIO object, automatically.
Obviously, type() is the wrong direction in this context, because
that "automatically" part is important.

But type() is also difficult to do right, even if you don't care
about polymorphism, because polymorphism is there whether you
want it or not. What if you have been checking for StringType
instead of list or tuple, and someone passes a Unicode object?
Is that a string? Is it StringType? You're not ready for that
if you haven't explicitly accounted for it, and there's lots of
Python code still in use that was written before there was such
a thing as a Unicode object.

Donn Cave, (e-mail address removed)
 
B

Bryan Castillo

On the other hand, if you want to support a string as an single
value instead of a list or tuple of values, then you're not
really talking about polymorphism here anyway. When a function
decides to support various unrelated types for a particular
parameter, I don't know what you call that, but it isn't
polymorphism in any useful sense.

The original poster is talking about function/method overloading as
you have in C++ or Java.

<snip>
 
A

Aahz

What's the standard way to implement polymorphic behavior in a python
method, given that method arguments can't declare their types as
they're being passed in, and method definitions don't have signatures?

For instance, if I wanted to write a method that auto-detected whether
it was being passed a string or a tuple/list, how would I do so
without using type() to identify the parameter's type? Using type() is
deprecated in the documentation I've read.

Generally speaking, in Python you simply create two different callables.
 
D

Donn Cave

Quoth (e-mail address removed) (Bryan Castillo):
....
|> On the other hand, if you want to support a string as an single
|> value instead of a list or tuple of values, then you're not
|> really talking about polymorphism here anyway. When a function
|> decides to support various unrelated types for a particular
|> parameter, I don't know what you call that, but it isn't
|> polymorphism in any useful sense.
|
| The original poster is talking about function/method overloading as
| you have in C++ or Java.

I don't think we can reasonably call anything function overloading
in Python, but at any rate, whatever you call it, it isn't polymorphism.

Donn Cave, (e-mail address removed)
 
D

Duncan Booth

I use:

class foo:
_stringtype=type('')
_tupletype=type(())
_listtype=type([])

You could just use the builtin names already supplied for these: str,
tuple, and list have the same values you just assigned to _stringtype,
_tupletype, and _listtype. Also, you forgot about unicode.
def __init__(self, variable):
if type(variable) == _stringtype:
self.variable=variable # check for string type
if type(variable) in (_listtype, tupletype):
self.variable=str(variable) # check for list/tuple
.

If anyone has been subclassing str, list or tuple this won't work. You may
not subclass builtin types very often, but it doesn't really hurt to use
isinstance instead. That's why it is better to write:

if isinstance(variable, (str, unicode)):
...

or:

if isinstance(variable, basestring):
...

as either of these will catch subclassing.
 
P

Peter Otten

Larry said:
I use type() quite a lot. I poked around and couldn't
find where it was being deprecated. I did see that
types module is slated for deprecation. Maybe I
overlooked it?

I use:

class foo:
_stringtype=type('')
_tupletype=type(())
_listtype=type([])

def __init__(self, variable):
if type(variable) == _stringtype:
self.variable=variable # check for string type
if type(variable) in (_listtype, tupletype):
self.variable=str(variable) # check for list/tuple

I would change that to

def __init__(self, v):
self.variable = str(v)

The fact that str() is a function hides what is really going on, so I'll
make it explicit:

def __init__(self, v):
self.variable = v.__str__()

In general everything that differs from class to class should be delegated
to the class that needs the special behaviour. Of course for classes that
aren't under your control it may sometimes be more practical to
special-case them with isinstance() checks than to subclass.

Peter
 
L

Larry Bates

Duncan,

Thanks for your reply to my post. As all programmers
I have adopted coding "techniques" that I see in others
code. The technique I suggested is lifted directly
from ReportLab code. I don't know if it predates the
isinstance function or not (which may explain why it
is not used). BTW-Your example that includes basestring
apparently only works on Python 2.3. Anyway, I
learned something today.

Thanks again,
Larry Bates
Syscon, Inc.

Duncan Booth said:
I use:

class foo:
_stringtype=type('')
_tupletype=type(())
_listtype=type([])

You could just use the builtin names already supplied for these: str,
tuple, and list have the same values you just assigned to _stringtype,
_tupletype, and _listtype. Also, you forgot about unicode.
def __init__(self, variable):
if type(variable) == _stringtype:
self.variable=variable # check for string type
if type(variable) in (_listtype, tupletype):
self.variable=str(variable) # check for list/tuple
.

If anyone has been subclassing str, list or tuple this won't work. You may
not subclass builtin types very often, but it doesn't really hurt to use
isinstance instead. That's why it is better to write:

if isinstance(variable, (str, unicode)):
...

or:

if isinstance(variable, basestring):
...

as either of these will catch subclassing.
 
P

pugnatio2

Thanks to all who replied. I think I've got it straight now, and by
the way I did use "polymorphism" incorrectly; I should have said
"method overloading."

I guess I have my choice between separate callables and using type()
or isinstance().

What I had hoped to do was something like:

xmlDoc = myFormat2XML(obj)

where 'obj' could be either a text string or a sequence of lines. It's
not just a problem of whether a scalar or sequence object is passed
in. Strings, lists, and tuples are all sequences.

The deprecation I read, about avoiding type() (p. 129 of _Python in a
Nutshell_) said it interfered with (true) polymorphism (via
inheritance).

Cheers,

--tb
 
G

Gary Herron

Thanks to all who replied. I think I've got it straight now, and by
the way I did use "polymorphism" incorrectly; I should have said
"method overloading."

I guess I have my choice between separate callables and using type()
or isinstance().

What I had hoped to do was something like:

xmlDoc = myFormat2XML(obj)

where 'obj' could be either a text string or a sequence of lines. It's
not just a problem of whether a scalar or sequence object is passed
in. Strings, lists, and tuples are all sequences.

The deprecation I read, about avoiding type() (p. 129 of _Python in a
Nutshell_) said it interfered with (true) polymorphism (via
inheritance).

That deprecation is correct. Instead of using type(), use
isinstance(param, type).

The call to isinstance returns True if param is an instance of the
given type or any subtype thereof. This works correctly for
inheritance, giving you the polymorphism you want.

Gary Herron
 
D

Donn Cave

Gary Herron said:
That deprecation is correct. Instead of using type(), use
isinstance(param, type).

The call to isinstance returns True if param is an instance of the
given type or any subtype thereof. This works correctly for
inheritance, giving you the polymorphism you want.

Subtype polymorphism! Is that how it works in Python, though?
0

Who cares if it's a subtype?

Donn Cave, (e-mail address removed)
 
H

Hung Jung Lu

Thanks to all who replied. I think I've got it straight now, and by
the way I did use "polymorphism" incorrectly; I should have said
"method overloading."

You did not make a mistake. Others did.

http://en.wikipedia.org/wiki/Polymorphism_(computer_science)

In terms of code factorization, polymorphism simply means
"factorization of a name". Same name, different code. The actual code
used is decided by some underlying/implicit mechanism.

Anything that fits the criterion "same name, different code" can be
called polymorphism. It can be applied to data or functions/methods
alike.

"Polymorphism" itself means several things. In a sense, the term
itself is polymorhic: same word, several meanings. The precise meaning
depends on context. If you understand this last part, you understand
polymorphism. :)

regards,

Hung Jung
 
K

Kevin Dahlhausen

There's a sample of an overloading mechanism implemented in the python
fltk wrappers on sourceforge.
 
K

Kevin Dahlhausen

There's a sample of an overloading mechanism implemented in the python
fltk wrappers on sourceforge.
 

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
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top