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

Paul Moore p.f.moore at gmail.com
Tue Sep 29 16:56:23 CEST 2015

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 = []
        self.vertices = vertices
    if edges is None:
        self.edges = []
        self.edges = edges
    if weights is None:
        self.weights = {}
        self.weights = weights
    if source_nodes is None:
        self.source_nodes = []
        self.source_nodes = source_nodes

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.

In this case, my preference is probably (1) a default() function, (2)
or?, (3) multi-line if. The default() function approach can be used
for cases where the condition is something *other* than "is None" so
that one edges ahead of or? because it's more flexible... (although
(1) wouldn't be an option if short-circuiting really mattered...)

In practice, of course, I never write a default() function at the
moment, I just use multi-line ifs. Whether that means I'd use an or?
operator, I don't know. Probably - but I'd likely consider it a bit of
a "too many ways of doing the same thing" wart at the same time...


More information about the Python-ideas mailing list