[Python-ideas] Enhancing vars()

Steven D'Aprano steve at pearwood.info
Tue Dec 13 18:49:14 EST 2016


On Wed, Dec 14, 2016 at 12:58:16AM +0200, Serhiy Storchaka wrote:
> On 13.12.16 01:45, Steven D'Aprano wrote:
> >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.
> 
> http://bugs.python.org/issue13290
> http://mail.python.org/pipermail/python-dev/2012-October/122011.html

Thanks Serhiy!

Glad to see I'm not the only one with this idea.

I think:

- the behaviour of locals() (and vars() when given no argument, where it 
returns locals()) is anomalous and should not be copied unless we really 
need to.

- Other Python implementations don't always emulate the weird behaviour 
of locals(), for example I think IronPython locals() is writeable, and 
the local variables do change.

steve at orac:~$ ipy
IronPython 2.6 Beta 2 DEBUG (2.6.0.20) on .NET 2.0.50727.1433
Type "help", "copyright", "credits" or "license" for more information.
>>> def test():
...     a = 1
...     locals()['a'] = 99
...     print a
...
>>> test()
99

CPython will print 1 instead.

So CPython locals() is an implementation detail and we shouldn't feel 
the need to copy it's weird behaviour.

When given an object, vars(obj) should return a dict-like object which 
is a read/write proxy to the object's namespace. If the object has a 
__dict__ but no __slots__, then there's no need to change anything: it 
can keep the current behaviour and just return the dict itself:

assert vars(obj) is obj.__dict__


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.

If the objects has *neither* __slots__ nor __dict__, vars can probably 
raise a TypeError.



-- 
Steve


More information about the Python-ideas mailing list