我有下面的类,它的目的是模仿一个dict
,而不是一个子类:
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 = {}
这将在使用时产生以下输出:
>>> 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__
难道它不应该到达__getattr__("__dict__")
,因为self.__dict__
应该已经存在了,因为它是一个对象?
我已经在Python2.6中使用了几个月的程序中成功地使用了这个对象(嗯,一个本质上相同的对象),并试图升级到Python3.4。根据我在网上所能找到的一切,Python 3应该和Python 2一样处理这个问题。
编辑:类似于this other question,但这个问题处理的是根本不调用__getattr__
。不过,两者显然都与新风格和旧风格的课程有关。
发布于 2015-04-01 12:21:30
您正在重写__getattribute__
(这是属性查找的默认实现),其方式是在查找__dict__
时引发NameError
。这会触发对__getattr__
的调用,这反过来会引发一个AttributeError
。其结果正是您实际要求的(如果不是您所期望的)。
FWIW:
eval("self.%s" % name)
,使用getattr(obj, name)
__getattribute__
(或__setattr__
)super()
)。另外:在Python2.7中,您发布的代码“原样”不起作用(对self._d.__setattr__
的调用引发了一个AttributeError,并使DB
成为一个新样式的类,其方式与Python3.x中完全相同。
https://stackoverflow.com/questions/29399161
复制