[Python-Dev] inconsistency when swapping obj.__dict__ with a dict-like object...

Brett C. bac at OCF.Berkeley.EDU
Wed Apr 6 04:46:07 CEST 2005


Alex A. Naanou wrote:
> Hi!
> 
> here is a simple piece of code
> <pre>
> ---cut---
> class Dict(dict):
>     def __init__(self, dct={}):
>         self._dict = dct
>     def __getitem__(self, name):
>         return self._dct[name]
>     def __setitem__(self, name, value):
>         self._dct[name] = value
>     def __delitem__(self, name):
>         del self._dct[name]
>     def __contains__(self, name):
>         return name in self._dct
>     def __iter__(self):
>         return iter(self._dct)
> 
> class A(object):
>     def __new__(cls, *p, **n):
>         o = object.__new__(cls)
>         o.__dict__ = Dict()
>         return o
> 
> a = A()
> a.xxx = 123
> print a.__dict__._dict
> a.__dict__._dict['yyy'] = 321
> print a.yyy
> 
> --uncut--
> </pre>
> 
> Here there are two problems, the first is minor, and it is that
> anything assigned to the __dict__ attribute is checked to be a
> descendant of the dict class (mixing this in does not seem to work)...
> and the second problem is a real annoyance, it is that the mapping
> protocol supported by the Dict object in the example above is not used
> by the attribute access mechanics (the same thing that once happened
> in exec)...
> 

Actually, overriding __getattribute__() does work; __getattr__() and
__getitem__() doesn't.  This was brought up last month at some point without
any resolve (I think Steve Bethard pointed it out).

> P.S. (IMHO) the type check here is not that necessary (at least in its
> current state), as what we need to assert is not the relation to the
> dict class but the support of the mapping protocol....
> 

Semantically necessary, no.  But simplicity- and performance-wise, maybe.  If
you grep around in Objects/classobject.c, for instance, you will see
PyClassObject.cl_dict is accessed using PyDict_GetItem() and I spotted at least
one use of PyDict_DelItem().  To use the mapping protocol would require
changing all of these to PyObject_GetItem() and such.

Which will be a performance penalty compared to PyDict_GetItem().  So the
question is whether the flexibility is worth it.

-Brett


More information about the Python-Dev mailing list