[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