better ergonomics for untyped dictionary access?
better ergonomics for untyped dictionary access?
Posted Jan 21, 2025 23:45 UTC (Tue) by NYKevin (subscriber, #129325)In reply to: better ergonomics for untyped dictionary access? by ianmcc
Parent article: Reviving None-aware operators for Python
If you write parsed_json.get("key1")?.get("key12")?.get("key123"), then the get() method on dicts already returns None when there's no such key, so the only thing that ?. can actually be doing is None-coalescing self. That is, if you write None?.get("key12"), it evaluates to None and the get() method is never even looked up, let alone called (which is necessary, because None has no get() method to look up). But if self is not None and get() does get called, then it behaves exactly as it would with the regular foo.get() syntax. This is nice and predictable, and I see no obvious problem with it aside from the fact that it makes the language slightly more complicated.
If you write parsed_json?["key1"]?["key12"?["key123"], then we need foo?[...] to make two changes in semantics from foo[]. It has to do None-coalescing as in the previous paragraph, but it also has to return None instead of raising KeyError. The latter is not necessarily a problem by itself, because we could imagine splitting the __getitem__ magic method into two magic methods as was done with the division operator, but for it to also invoke None-coalescing at the callsite feels like a bridge too far to me. There's too much implicit behavior packed into one operator.
You could work around that problem by defining the new magic method on NoneType, so that None?[anything] always evaluates to None, but is still looked up and called like any other magic method. Then there wouldn't need to be any special None-coalescing behavior at the callsite. I'm not sure how I feel about that approach, but I suppose it would at least be logically coherent. The downside is that we usually expect None to have no special behavior, and this might be seen as breaking that rule.