I have a Python function in which I am doing some sanitisation of the input parameters:
def func(param1, param2, param3):
param1 = param1 or ''
param2 = param2 or ''
param3 = param3 or ''
This caters for the arguments being passed as None rather than empty strings. Is there an easier/more concise way to loop round the function parameters to apply such an expression to all of them. My actual function has nine parameters.
-
You probably want something more like this:
def func(param1='', param2='', param3=''):
It's far more concise and idiomatic.
See http://docs.python.org/tutorial/controlflow.html#default-argument-values
Mat : I have some default argument values in my real function, but I am still concerned where parameters are passed with a value of 'None'. For example, I could call func(None, None).mipadi : That won't do what he wants -- you could still pass 'None' as a parameter.Kamil Kisiel : Right, sorry, I misunderstood the question. In that case, I recommend Kiv's answer below. -
def func(x='', y='', z='hooray!'): print x, y, z In [2]: f('test') test hooray! In [3]: f('test', 'and') test and hooray! In [4]: f('test', 'and', 'done!') test and done!
-
You could do some list manipulation:
def func(param1, param2, param3): param1, param2, param3 = map(lambda x: x or '', (param1, param2, param3))
but I'm not sure that's better than just writing out the nine lines, since once you get to nine parameters, that's a heinously long line.
You could change the declaration of the function:
def func(*args): param1, param2, param3 = map(lambda x: x or '', args)
but then you lose the documentation that comes from having real parameter names, as well as the possibility of changing the defaults, etc. And you still have a pretty fugly line there to unpack them.
I say write out the nine lines, or change the function to have fewer parameters: nine is kind of a lot anyway!
-
This looks like a good job for a decorator. How about this:
def sanitized(func): def sfunc(*args, **kwds): return func(*[arg or '' for arg in args], **dict((k, v or '') for k,v in kwds.iteritems())) sfunc.func_name = func.func_name sfunc.func_doc = func.func_doc return sfunc
You would use this on your function like so:
@sanitized def func(param1, param2, param3): print param1, param2, param3
Then the parameters will be replaced by the empty string if they are false:
>>> func('foo', None, 'spam') foo spam
(Note that this will still mess up the function signature as Ned Batchelder points out in his answer. To fix that you could use Michele Simionato's decorator module-- I think you'd just need to add a
@decorator
before the definition ofsanitized
)Kiv : Does this work with keyword arguments though?Kiv : I think you also need to pass along the kwargs too: **dict((k, arg or '') for k, arg in kwargs.items()))dF : Fixed to support kwargs, thanks KivKiv : Yes, this is by far the best solution (other than refactoring the original code to not require it.)Autoplectic : you should probably change the `arg or ''` to `'' if arg is None else arg` or something similar just in case arg is 0 or {} or something non-None.
0 comments:
Post a Comment