
On Mon, Jul 30, 2018 at 12:41:20PM -0500, Abe Dillon wrote: [Rhodri James]
On 29/07/18 16:12, Abe Dillon wrote:
spam?.eggs.cheese.aardvark # why would you ever do this?
If you knew that if you really have something in "spam", your program guarantees it will have an "eggs" attribute with a "cheese" attribute, etc, you just don't know if "spam" is not None. It's the same insider knowledge you would use if you wrote it out as
spam.eggs.cheese.aardvark if spam is not None else None
That's not the equivalent as described in PEP 505.
Yes it is. Rhodri is correct, although I admit that I hadn't realised this point myself until he pointed it out. (That is why until now I've been writing examples like "spam?.eggs?.cheese?.aardvark" which is redundant.) The abstract says: The "None-aware attribute access" operator ?. ("maybe dot") evaluates the complete expression if the left hand side evaluates to a value that is not None and later on the PEP says: When a None-aware operator is present, the left-to-right evaluation may be short-circuited. For example, await a?.b(c).d?[e] is evaluated: _v = a if _v is not None: _v = _v.b _v = _v(c) _v = _v.d if _v is not None: _v = _v[e] await _v I admit the example isn't the clearest. The inclusion of "await" doesn't seem helpful to me (if anything, the opposite, since "await None" will fail) and perhaps it would be clearer to write it as: _v = a if _v is not None: _v = _v.b(c).d if _v is not None: _v = _v[e] The PEP also says: Parenthesised expressions are handled by the atom rule (not shown above), which will implicitly terminate the short- circuiting behaviour of the above transformation. which again isn't too clear, and the example given seems complicated enough to obfuscate the point rather than illustrate it, but if I'm reading it correctly, the behaviour you expected would have to be written as (spam?.eggs).cheese.aardvark which would likely fail since None has no cheese attribute. The bottom line is that in any unparenthesized chain of maybe-dot and maybe-subscript operations, only the first needs to be "maybe" as that will short-circuit the rest of the expression. Figuratively speaking, it is as if we had: spam?(.eggs.cheese.aardvark) where the () are used for grouping, not function call. -- Steve