Re: [Python-ideas] Enhancing vars()
I'm +1. This bites me far too often. > in the past developers were encouraged to put only "useful" attributes in __dir__. Good. If I'm getting vars() I really only want the useful ones. If I need interesting/secret ones then I'll getattr for them. Cheers, Steve Top-posted from my Windows Phone -Original Message- From: "Alexander Belopolsky" Sent: 12/12/2016 19:47 To: "Steven D'Aprano" Cc: "python-ideas" Subject: Re: [Python-ideas] Enhancing vars() On Mon, Dec 12, 2016 at 6:45 PM, Steven D'Aprano wrote: 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. How do you propose dealing with classes defined in C? Their objects don't have __slots__. One possibility is to use __dir__ or dir(), but those can return anything and in the past developers were encouraged to put only "useful" attributes in __dir__.___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Enhancing vars()
On Mon, Dec 12, 2016 at 6:45 PM, Steven D'Aprano wrote: > 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. > How do you propose dealing with classes defined in C? Their objects don't have __slots__. One possibility is to use __dir__ or dir(), but those can return anything and in the past developers were encouraged to put only "useful" attributes in __dir__. ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Enhancing vars()
On 12/12/2016 03:45 PM, Steven D'Aprano wrote: 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. +1 -- ~Ethan~ ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Enhancing vars()
On 12/12/2016 6:45 PM, Steven D'Aprano wrote: 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: +1 I believe this was mentioned as a possibility on some issue , but I cannot find it. Does vars currently work for things with dict proxies instead of dicts? 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? -- Terry Jan Reedy ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Enhancing vars()
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/