I have the following class which is meant to imitate a dict
without actually being a subclass:
class DB:
def __getattribute__(self, name):
print('__getattribute__("%s")' % name)
if name.startswith('__') and name not in ['__init__', '__new__',
'__dict__', '__getattribute__', '__getattr__', '__setattr__',
'__delattr__', '__doc__', '__module__', '__del__', '__hash__']:
return eval('self._d.%s' % name)
print('it is not being diverted to self._d')
raise AttributeError(name)
def __getattr__(self, name):
print('__getattr__("%s")' % name)
if name.startswith('__'):
raise AttributeError(name)
return eval('self._d.%s' % name)
def __setattr__(self, name, val):
if name == '_d':
self.__dict__[name] = val
else:
return self._d.__setattr__(name, val)
def __delattr__(self, name):
if name == '_d':
del self.__dict__[name]
else:
return self._d.__delattr__(name)
def __init__(self):
self._d = {}
This produces the following output when used:
>>> d = DB()
__getattribute__("__dict__")
it is not being diverted to self._d
__getattr__("__dict__")
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
d = DB()
File "<pyshell#1>", line 31, in __init__
self._d = {}
File "<pyshell#1>", line 20, in __setattr__
self.__dict__[name] = val
File "<pyshell#1>", line 15, in __getattr__
raise AttributeError(name)
AttributeError: __dict__
Shouldn't it never get to __getattr__("__dict__")
, since self.__dict__
should already exist by virtue of this being an object?
I have been using this object (well, an essentially identical object) successfully in a program I have been using for several months in Python 2.6 and am trying to upgrade to Python 3.4. According to everything I can find online, Python 3 should be treating this the same as Python 2.
Edit: Similar to this other question but that question deals with __getattr__
not being called at all. Both are apparently related to new-style vs. old-style classes, though.