On Wed, Mar 05, 2014 at 12:57:03PM -0800, Thomas Wouters wrote: > On Thu, Feb 27, 2014 at 1:29 PM, Chris Angelico <ros...@gmail.com> wrote: > > > +Had this facility existed early in Python's history, there would have been > > +no need to create dict.get() and related methods; > > > FWIW, after experimenting and some consideration I've come to the > conclusion that this is incorrect. 'd[k] except KeyError: default' is still > much broader than dict.get(k):
I don't think your example proves what you think it does. I think it demonstrates a bug in the dict.get method. The documentation for get states clearly that get will never raise KeyError: Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError. http://docs.python.org/3/library/stdtypes.html#dict.get but your example demonstrates that in fact it can raise KeyError (albeit under some rather unusual circumstances): > Python 3.4.0rc1+ (default:aa2ae744e701+, Feb 24 2014, 01:22:15) > [GCC 4.6.3] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> expensive_calculation = hash > >>> class C: > ... _hash_cache = {} > ... def __init__(self, value): > ... self.value = value > ... if value not in self._hash_cache: > ... self._hash_cache[value] = expensive_calculation(value) > ... def __hash__(self): > ... return self._hash_cache[self.value] > ... def __eq__(self, other): > ... return self.value == other > ... > >>> a, b, c, d = C(1), C(2), C(3), C(4) > >>> D = {a: 1, b: 2, c: 3, d: 4} > >>> a.value = 5 > >>> print("except expr:", (D[a] except KeyError: 'default')) > except expr: default > >>> print("dict.get:", D.get(a, 'default')) > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > File "<stdin>", line 8, in __hash__ > KeyError: 5 According to the documentation, this behaviour is wrong. Now, you might argue that the documentation is wrong. I'm sympathetic to that argument, but *as documented now*, dict.get is documented as being logically equivalent to: try: return d[key] except KeyError: return default The fact that it actually isn't is an artifact of the specific implementation used. If it were a deliberate design choice, that design is not reflected in the documentation. Whether the current behaviour is wrong, or the documentation is wrong, is irrelevant to the question of whether or not the developers back in nineteen-ninety-whatever would have choosen to add dict.get had there been syntax for catching the KeyError in an expression. Perhaps they would have argued: "Sure, you can catch the KeyError yourself, but 'get' is a fundamental operation for mappings, and I think that dict should implement a 'get' method just to be complete." Or perhaps not. Some developers prefer minimalist APIs, some developers prefer more exhaustive APIs. Regardless of what might have happened back in 199x when dict.get was first discussed, I think we can agree that an except expression will lower the pressure on Python to add *more* "get-like" methods, or add default arguments, in the future. -- Steven _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com