On Wed, Dec 14, 2016 at 12:12:39AM +0000, Emanuel Barry wrote: > > From Steven D'Aprano > > Sent: Tuesday, December 13, 2016 6:49 PM > > To: python-ideas@python.org > > Subject: Re: [Python-ideas] Enhancing vars() > > > > But if the object has __slots__, with or without a __dict__, then vars > > should return a proxy which direct reads and writes to the correct slot > > or dict. > > > > It might be helpful to have a slotsproxy object which provides a > > dict-like interface to an object with __slots__ but no __dict__, and > > build support for both __slots__ and a __dict__ on top of that. > > That might be a bit tricky, for example, it's possible that a class has a > `foo` slot *and* a `foo` instance attribute (by virtue of subclasses). What > would you do in that case?
vars() shouldn't need to care about inheritance: it only cares about the object's own individual namespace, not attributes inherited from the class or superclasses. That's how vars() works now: py> class C: ... cheese = 1 ... py> obj = C() py> ns = vars(obj) py> 'cheese' in ns False The only difference here is that if the direct parent class has __slots__, the instance will use them instead of (or in addition to) a __dict__. We don't need to care about superclass __slots__, because they aren't inherited. > Or what if there's a slot that doesn't have any > value (i.e. raises AttributeError on access, but exists on the class > nonetheless), but an instance attribute with the same name exists? And so > on. Only the *list of slot names* exists on the class. The slots themselves are part of the instance. Nevertheless, you are right: a slot can be defined, but not assigned to. That has to be treated as if the slot didn't exist: py> class D: ... __slots__ = ['spam'] ... py> d = D() py> hasattr(d, 'spam') False So I would expect that 'spam' in vars(d) should likewise return False, until such time that d.spam is assigned too. The same applies even if the object has a __dict__. The slot always takes precedence, even if the slot isn't filled in. py> class E: ... __slots__ = ['spam', '__dict__'] ... py> e = E() py> e.__dict__['spam'] = 1 py> hasattr(e, 'spam') False > > If the objects has *neither* __slots__ nor __dict__, vars can probably > > raise a TypeError. > > Is that even possible in pure Python? The only object I know that can do > this is `object`, but some other C objects might do that too. I don't think pure Python classes can do this, at least not without some metaclass trickery, but certainly `object` itself lacks both __slots__ and instance __dict__, and C objects can do the same (so I'm told). -- 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/