argument type

Steven Bethard steven.bethard at gmail.com
Tue Dec 28 00:51:58 EST 2004


It's me wrote:
> Steve,
> 
> The argument I wish to pass is either one string, or a list of strings, or a
> tuple of strings.
> 
> For instance, I have:
> 
>     def abc(arg1, arg2, arg3)
> 
> Let say that I expect arg1 and arg3 to be a number, and arg2 can be either
> one string, or a bunch of strings and I need to do something on each of the
> strings passed down.  So, using the isinstance function suggested, I can
> have:
> 
>     def abc(arg1, arg2, arg3)
>         if isinstance(arg2,(list,tuple)):
>             for item in arg2:
>                 abc(arg1, item)
>         else:
>             # do whatever with arg2 and I know now arg2 is a single instance
> of a string
>     ...
> 
> This way, when I invoke the function, I don't have to always remember the []
> like:
> 
>     abc(1,["String 1",],5)
> 
> I can simply do:
> 
>     abc(1,"String 1",5)
> 
> and likewise, I can do:
> 
>     abc(1,["String 1","String 2"],5)
> 
> Am I on the right track?

Yeah, given those constraints, you basically have two options -- check 
for list/tuple (as you have above) or check for str/unicode (as I do 
below).  I personally prefer the latter because it seems much more 
likely that users will define alternate collection classes than that 
users will define alternate string classes.  My code would look like:

     def abc(arg1, arg2, arg3):
         if not isinstance(arg2, basestring):
             for item in arg2:
                 abc(arg1, item, arg3)
         else:
             # do whatever with arg2 (guaranteed to be a string)

That way if you later call your code with, say:

     abc(1, set(["String 1", "String 2"]), 5)

or

     abc(1, collections.deque(["String 1", "String 2"]), 5)

it still works.


Steve


P.S.  My real preference here would be to change the order of your 
arguments and write the function as:

     def abc(arg1, arg3, *arg2s)
         for arg2 in arg2s:
             # do whatever with arg2 (should be a string)

and then write your function calls as:

      abc(1, 5, "String 1")
      abc(1, 5, "String 1", "String 2")

Then you don't ever have to remember []s. ;-)  But if you really are 
stuck with arg2 as the second argument, I'd probably go for testing 
isinstance(x, basestring).

Steve



More information about the Python-list mailing list