Nicolas Vigier wrote: > Hello, > > I have in my python script a function that look like this : > > def my_function(arg1, arg2, opt1=0, opt2=1, opt3=42): > if type(arg1) is ListType:
How should it behave with tuples or subclasses of List ? Or if it's any other iterable ? Testing against the *exact* type of an object is usually not a good idea in Python. You should at least replace this test with something like: if isinstance(arg1, list): #code here or even better: if hasattr(arg1, '__iter__'): # code here or still even better (for maintenance at least): def my_function(arg1, ...): def kind_of_list(arg): return hasattr(arg1, '__iter__') if kind_of_list(arg1): # code here > for a in arg1: > my_function(a, arg2, opt1=opt1, opt2=opt2, opt3=opt3) > return > if type(arg2) is ListType: > for a in arg2: > my_function(arg1, a, opt1=opt1, opt2=opt2, opt3=opt3) > return > ... then here the real function code > > I'm new to python, so I was wondering if there is a better way to do that. > The reason for a recursive function here is to be able to give lists for > the first 2 args <IMHO> If possible, you'd better decide for a simplest API. Either always pass a kind_of_list, or let the user take care of the loop. </IMHO> You can also use two functions, one that actually do the job and the other that do the test and wrap the call to the first (note that the first function doesn't need to be part of the public API). This makes code more readable, and cleany decouple effective task from the test_type_and_dispatch mechanism. ie: def doTheJob(arg, opt1=None, opt2=None, opt3=None): # effective code here pass def callDoTheJob(arg1, arg2, opt1=0, opt2=1, opt3=42): if is_kind_of_list(arg1): for a in arg1: callDoTheJob(a, arg2, ....) elif is_kind_of_list(arg2): for a in arg2: callDoTheJob(arg1, a, ....) else: doTheJob(arg1, arg2, ...) > (I could as well use only a simple 'for' without a > recursive call). This can be better when it comes to perfs. I find the recursive solution to be more readable (but this is a matter of taste), and it has the advantage/drawback (depends on the real usage) that nested lists are handled for (almost) any depth of nesting. > The problem I have here, is that as I'm working on this > script, I often change the prototype of the function, and each time I > have to think about changing the recursive call too. Is there a way that > I can do a recursive call and say something like "keep all the same > arguments except this one" ? If this only concern the 'opts' args: def callDoTheJob(arg1, arg2, **kw): if is_kind_of_list(arg1): for a in arg1: callDoTheJob(a, arg2, **kw) elif is_kind_of_list(arg2): for a in arg2: callDoTheJob(arg1, a, **kw) else: doTheJob(arg1, arg2, **kw) hth -- bruno desthuilliers python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')])" -- http://mail.python.org/mailman/listinfo/python-list