In general, directly accessing dunders is a bit of a code smell. (I exclude writing dunder methods in your classes, of course.) There's usually a built-in or similar to do the job for you, e.g. instead of iterator.__next__() we should use next(iterator).
One of the lesser-known ones is vars(obj), which should be used in place of obj.__dict__. Unfortunately, vars() is less useful than it might be, since not all objects have a __dict__. Some objects have __slots__ instead, or even both. That is considered an implementation detail of the object. Proposal: enhance vars() to return a proxy to the object namespace, regardless of whether said namespace is __dict__ itself, or a number of __slots__, or both. Here is a woefully incompete and untested prototype: class VarsProxy(object): def __init__(self, obj): if not (hasattr(obj, '__dict__') or hasattr(obj, '__slots__')): raise TypeError('object has no namespace') self._obj = obj def __getitem__(self, key): slots = getattr(type(self), '__slots__', None) # see inspect.getattr__static for a more correct implementation if slots is not None and key in slots: # return the content of the slot, without any inheritance. return getattr(self._obj, key) else: return self._obj.__dict__[key] def __setitem__(self, key, value): ... def __delitem__(self, key): ... One complication: it is possible for the slot and the __dict__ to both contain the key. In 3.5 that ambiguity is resolved in favour of the slot: py> class X: ... __slots__ = ['spam', '__dict__'] ... def __init__(self): ... self.spam = 'slot' ... self.__dict__['spam'] = 'dict' ... py> x = X() py> x.spam 'slot' Although __slots__ are uncommon, this would clearly distinguish vars(obj) from obj.__dict__ and strongly encourage the use of vars() over direct access to the dunder attribute. Thoughts? -- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/