Implicit lists

Erik Max Francis max at alcyone.com
Fri Jan 31 22:26:10 EST 2003


Max M wrote:

> You will need to check if the argument is a list or a string in all
> the
> code wich calls one of the function.
> 
> if type(options) == type(''):
>      getWhereByOne(options)
> else:
>      getWhere(options)
> 
> This is no better than the first option.

Why do you _have_ to check?  You're doing precisely the thing that
you're not supposed to do in dynamic languages; you're limiting the
types that can be passed to them unnecessarily.

Having two interfaces where one takes "a thing" and the other takes "a
sequence of things" is totally reasonable, since one will be treated as
things, and the other will be treated as a sequence of things.

In your specific case those things are strings, but that analysis
doesn't generalize fully.

> So the sane approach is to do the check inside the function:
> 
>      def getWhere(options):
>          if type(options) == type(''): # I *know* this sucks!
>              options = [options]
>          return 'SELECT * FROM table WHERE %s' % ' or '.join(
>                 ['option=%s' for opt in options])
> 
> This will lead to far the most simple use of the function.

That isn't totally unreasonable, provided you're sure that you always
want them to be strings, or something else (which will be interpreted as
a sequence of strings).  (But even then, what about Unicode strings? 
They'd fail the test.)

Again, this is the only sort of polymporphic interface that makes any
sort of sense -- where you know that you either want a simple,
fundamental type (like a numeric or a string), or something else.  In
this case, it's either a string, or a sequence of things (which are
presumably strings).

Note still that this case is limiting; your sequence case works properly
on objects that implement a __str__ method that does something
meaningful, but you can't pass a single one of those objects in, as it
will be treated as a sequence, with unpredictable results.

This, as I mentioned earlier, isn't totally unreasonable, since you're
checking against a fundamental type first, and then generalizing if that
wasn't it; the original poster was talking about testing to see if it's
a _sequence_ first (by testing whether it's a list or tuple) and then
behaving differently otherwise.  This is bad, because there are many
more types of sequences than just lists and tuples.

-- 
 Erik Max Francis / max at alcyone.com / http://www.alcyone.com/max/
 __ San Jose, CA, USA / 37 20 N 121 53 W / &tSftDotIotE
/  \ It is much safer to obey than to rule.
\__/ Thomas a Kempis
    Sade Deluxe / http://www.sadedeluxe.com/
 The ultimate Sade encyclopedia.




More information about the Python-list mailing list