[Python-ideas] PEP 505 (None coalescing operators) thoughts

Rob Cliffe rob.cliffe at btinternet.com
Tue Sep 29 18:20:45 CEST 2015



On 29/09/2015 15:56, Paul Moore wrote:
> On 29 September 2015 at 14:40, Eric Snow <ericsnowcurrently at gmail.com> wrote:
>>> For default parameters with mutable types as values,
>>> I usually write:
>>>
>>> def func(x=None):
>>>      if x is None:
>>>          x = []
>>>      ...
>> I do the same.  It has the right amount of explicitness and makes the
>> default-case branch more obvious (subjectively, of course) than the
>> proposed alternative:
>>
>> def func(x=None):
>>      x = x ?? []
> Looking at those two cases in close proximity like that, I have to say
> that the explicit if statement wins hands down.
>
> But it's not quite as obvious with multiple arguments where the target
> isn't the same as the parameter (for example with a constructor):
>
> def __init__(self, vertices=None, edges=None, weights=None, source_nodes=None):
>      if vertices is None:
>          self.vertices = []
>      else:
>          self.vertices = vertices
>      if edges is None:
>          self.edges = []
>      else:
>          self.edges = edges
>      if weights is None:
>          self.weights = {}
>      else:
>          self.weights = weights
>      if source_nodes is None:
>          self.source_nodes = []
>      else:
>          self.source_nodes = source_nodes
> vs
>
> def __init__(self, vertices=None, edges=None, weights=None, source_nodes=None):
>      self.vertices = vertices or? []
>      self.edges = edges or? []
>      self.weights = weights or? {}
>      self.source_nodes = source_nodes or? []
>
> Having said all of that, short circuiting is not important here, so
>
> def default(var, dflt):
>      if var is None:
>          return dflt
>      return var
>
> def __init__(self, vertices=None, edges=None, weights=None, source_nodes=None):
>      self.vertices = default(vertices, [])
>      self.edges = default(edges, [])
>      self.weights = default(weights, {})
>      self.source_nodes = default(source_nodes, [])
>
> is also an option.
>
>
Why not

def __init__(self, vertices=None, edges=None, weights=None, source_nodes=None):
     self.vertices     = vertices     if vertices     is not None else []
     self.edges        = edges        if edges        is not None else []
     self.weights      = weights      if weights      is not None else {}
     self.source_nodes = source_nodes if source_nodes is not None else []

Completely explicit.
Self-contained (you don't need to look up a helper function).
Reasonably compact (at least vertically).
Easy to make a change to one of the lines if the logic of that line changes.
Doesn't need a language change.
And if you align the lines (as I have attempted to, although different 
proportional fonts may make it look ragged),
it highlights the common structure of the lines *and* their differences 
(you can see that one line has "{}" instead of "[]" because it stands out).

Rob Cliffe


More information about the Python-ideas mailing list