Function Overloading Without Typechecking
Quinn Dunkan
quinn at hork.ugcs.caltech.edu
Wed Jan 16 15:28:23 EST 2002
On Tue, 15 Jan 2002 12:37:39 -0500, Michael Chermside <mcherm at destiny.com>
wrote:
>Well, that's fine, but I have gotten used to having method overloading
>in Java and C++. So I like to write things like this:
>
> def spamThemAll(stuffToSpam):
> if type(stuffToSpam) in types.StringTypes:
> stuffToSpam = stuffToSpam.split()
> for s in stuffToSpam:
> spam(s)
>
>That way I can invoke the method with two different kinds of values:
>
> spamThemAll( ['a', 'b', 'c'] )
> spamThemAll( 'a b c' )
>
>... and it automatically converts. Convenient, but dangerous. For
>instance, if I had used "type(stuffToSpam) == types.String" as my test,
>then it wouldn't have worked for unicode strings. And this version will
>probably break on some other type which I haven't prepared for (UserString).
>
>So what do I do? I can think of a few possibilities:
>
> 1) Just don't do it. Only accept one type and make the caller
> convert.
>
> [But this is awkward for the caller!]
Not in the above example:
spamThemAll('a b c'.split())
I've never run into a situation where I have to do much type conversion,
except string->whatever at the input stage.
> 2) Use optional keyword arguments:
> def spamThemAll( str=None, seq=None ):
> if str is not None:
> seq = str.split()
> for s in seq:
> spam(s)
>
> [But this makes the caller use keyword args always!]
Yeah, and it's gross besides because now you have a bunch of mutually
exclusive keywords.
> 3) Create multiple methods:
> def spamThemAll_withString(str):
> return spamThemAll_withSeq( str.split() )
>
> [But this creates annoying extra functions!]
Yeah, better to have a thought-out seperate set of functions to convert types
if you need to do lots of it for whatever reason, rather than lots of
*_from_foo *_to_bar. Combinatorial explosion, etc.
>How do those of you who are more experienced with this handle this issue?
I'd go for #1, but I almost never feel the need to play games with types like
that. The exception is occaisionally treating singleton as [singleton] in a
function that wants complicated nested structure, e.g.:
((attr1, (f1, ('bar', 'baz', 'faz')),
(attr2, (f2, ('zaf', 'zab')))
(attr3, (f3, 'qux')))) # last 'qux' short for ('qux',)
It's like lisp which lets you do
(let ((x nil)) ...)
or
(let ((x)) ...)
or
(let (x) ...)
More information about the Python-list
mailing list