Hmmm... well, I see your point. Unfortunately, even though it feels
incorrect to me, I do not (yet) have the breadth and depth of Python
experience to come up with an example that would display such exquisite
polymorphism. It also seems to me that such an example would be
non-trivial in nature.
Wrong on both counts. Let me give you a hint.
Take integers and lists. Count how many methods the two types have in
common. By my reckoning, they are:
__add__, __iadd__, __mul__, _imul__, __str__, __repr__, and
__nonzero__.
Also there are __getattribute__ and __setattr__, but lists and ints
share no common attributes. I don't think ints have any at all aside
from the special methods.
What this means is: any code that can work for both ints and lists
must use only these methods (this is not quite correct, but mostly
is). That eliminates probably 99.9% of code right off the bat.
Then you have to consider that some code that does use only these
attributes does something useful only for either ints or lists, not
both. Take this simple example:
def foil(a,b,c,d):
return a*b + a*d + b*c + b*d
This code works if a and c are both ints, or are both lists (while b
and d would have to be ints). It does something useful for ints and
other numeric types, but does it do anything useful for lists?
Third, there are cases where you have code that works for both ints
and lists, that does do something useful for both, but it makes no
sense to apply "if x" to it.
def print_if_true(x):
if x:
print x
This little piece of code might actually come in handy here and there,
but would it end up being used for numeric types a whole lot? It
seems like if you have an empty list you might reasonably want to
print nothing at all, but when you have a zero integer you usually
want to print the zero.
(However, you might reasonably want to print some object unless it's
None. You could then use this one function to handle that case as
well as the case with empty lists, instead of defining two functions,
like so:
print_if_not_empty(x):
if len(x)!=0:
print x
print_if_not_None(x):
if x is not None:
print x
But wait! What if you had a value that could be either an integer or
None? You can't use the "if x" variant because x could be False. So
you'd have to define the "if x is not None" variant anyway. I might
use the "if x" variant in throwaway scripts, but for anything
production I would prefer the explicit variants, partially because, as
shown above, even when "if x" does rear it's polymoprhic head, it
doesn't necessarily buy you much.
Nevertheless, I think this is probably the best example of the
enhanced polymorphism of "if x" yet. I'm kind of surprised no one
came up with it.)
In general, the ability to take advantage of "if x" polymorphism
across numeric, container, and other types depends on the something/
nothing dichotomy to be applicable. Something versus nothing is a
useless concept most of the time, but occasionally finds use in human
interaction cases such as printing.
So there you have it. This is why I didn't expect anyone to come up
with a good example: you just don't have a lot to work with.
Carl Banks