Share with undefined arguments more elegantly

The accepted paradigm for handling mutable default arguments is:

def func(self, a = None): if a is None: a = <some_initialisation> self.a = a 

As I could do this for a few arguments, I would need to write very similar 3 lines again and again. I find this to be non-pythonically a lot of text to read for a very very standard thing to do when initializing class objects or functions.

Is there an elegant single-line layer to replace the three lines associated with the potential undefined argument and the standard required copy to class instance variables?

+6
source share
4 answers

If the value "falsy" (0, empty string, list, dict, etc.) is not a valid value for a, you can reduce the initialization to one line:

 a = a or <initialize_object> 
+4
source

Another way to do the same:

 def func(self,**kwargs): self.a=kwargs.get('a',<a_initialization>) ... 

This extra bonus, the value a passed to the function may be None, and initialization will not overwrite it. The downside is that a user using the built-in help function will not be able to determine which keywords your functions are looking for unless you explicitly specify this in the docstring.

EDIT

Another comment. The user can call the above function with keywords that are not derived from the kwargs dictionary. In some cases, this is good (if you want, for example, passing keywords to another function). In other cases, this is not what you want. If you want to raise an error if the user provides an unknown keyword, you can do the following:

 def func(self,**kwargs): self.a=kwargs.pop('a',"Default_a") self.b=kwargs.pop('b',"Default_b") if(kwargs): raise ... #some appropriate exception...possibly using kwargs.keys() to say which keywords were not appropriate for this function. 
+3
source

You can do it

 def func(self, a=None): self.a = <some_initialisation> if a is None else a 

But why the obsession with one liner? I usually use the 3-line version, even if it repeats itself everywhere, because if your code is very simple for experienced Python programmers to read

+3
source

Just a small solution that I came up with using an additional function can be improved, of course:

defaultargs.py:

  def doInit(var, default_value,condition): if condition: var = default_value return var def func(a=None, b=None, c=None): a = doInit(a,5,(a is None or not isinstance(a,int))) b = doInit(b,10.0,(a is None or not isinstance(a,float))) c = doInit(c,"whatever",(a is None or not isinstance(c, str))) print a print b print c if __name__ == "__main__": func(10) func(None,12341.12) func("foo",None,"whowho") 

exit:

  10 10.0 whatever 5 10.0 whatever 5 10.0 whowho 

I like your question. :)

Edit: If you do not care about the type of variables, do not use isinstance ().

+1
source

Source: https://habr.com/ru/post/911613/


All Articles