Python属性访问错误
我试图在类(python2.7)中自定义属性访问。假设我定义了以下类:Python属性访问错误,python,oop,attributes,Python,Oop,Attributes,我试图在类(python2.7)中自定义属性访问。假设我定义了以下类: class testAttrAccess(object): def __init__(self): self.data = {"attr1":"value1","attr2":"value2"} def __getattr__(self,name): try: return self.data[name] except KeyError
class testAttrAccess(object):
def __init__(self):
self.data = {"attr1":"value1","attr2":"value2"}
def __getattr__(self,name):
try:
return self.data[name]
except KeyError:
pass
raise AttributeError
然后我得到:
In [85]: a = testAttrAccess()
In [86]: a.attr2
Out[86]: 'value2'
In [87]: a.__getattr__('attr2')
Out[87]: 'value2'
In [88]: a.__getattribute__('attr2')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/Users/laserson/temp/<ipython console> in <module>()
AttributeError: 'testAttrAccess' object has no attribute 'attr2'
[85]中的:a=testAttrAccess()
在[86]中:a.attr2
Out[86]:“value2”
在[87]中:a.。\uuuu getattr\uuuuu('attr2'))
Out[87]:“value2”
在[88]中:a.。\uuuuu getattribute\uuuuuu('attr2'))
---------------------------------------------------------------------------
AttributeError回溯(最近一次呼叫上次)
/用户/laserson/temp/in()
AttributeError:“testAttrAccess”对象没有属性“attr2”
但是,
如果该类还定义了\uuuuuGetAttr\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
,则后者将不会被调用,除非\uuuuuuuuuuuuuuuuuuuuuuuuGetAttribute\uuuuuu
因此,如果\uuuu getattribute\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
a.。\uuuu getattr\uuuuuuu
仅在a.\uuu dict\uuuuuu
中找不到该属性时才会调用
a.。\uuuu getattribute\uuuu
在所有情况下都会被调用(如果已定义)
如您所知,a.\uuuuuuGetAttribute(attr)
是类型(a)的语法糖。\uuuuuGetAttribute(a,attr)
,但由于此方法未在测试访问中定义,因此调用父方法对象。\uuuuGetAttribute(a,attr)
。从您的结果中,我们可以得出结论,调用\uuuuuu getattr\uuuu
的不是对象。可能是口译员处理的
您可以通过如下方式更改程序使其正常工作:
class testAttrAccess(object):
def __init__(self):
self.data = {"attr1": "value1", "attr2": "value2"}
def __getattribute__(self, name):
try:
return object.__getattribute__(self, name)
except AttributeError:
if name == "__getattr__":
return object.__getattribute__(self, "__getattribute__")
try:
return object.__getattribute__(self, "data")[name]
except KeyError:
raise AttributeError
a = testAttrAccess()
print a.attr2
print a.__getattr__('attr2')
print a.__getattribute__('attr2')
print a.qwerty
输出:
value2
value2
value2
Traceback (most recent call last):
File "test.py", line 20, in
print a.qwerty
File "test.py", line 13, in __getattribute__
raise AttributeError
AttributeError
价值2
价值2
价值2
回溯(最近一次呼叫最后一次):
文件“test.py”,第20行,在
打印a.qwerty
文件“test.py”,第13行,在__
提高属性错误
属性错误
这仅适用于python作为正常属性访问的一部分为您调用\uuuuuu getattribute\uuuu
的情况,而不是您自己调用\uuuu getattribute\uuuu
的情况。基本上,您几乎不应该调用形式为\uuuufoo\uucode>的python方法,这些方法用于实现依赖于其他操作的行为。受@lazyr的启发,此解决方案似乎也能工作。这对我来说似乎更简单…它会给任何人带来危险吗
class testAttrAccess(object):
def __init__(self):
self.data = {"attr1":"value1","attr2":"value2"}
def __getattribute__(self,name):
try:
return object.__getattribute__(self,name)
except AttributeError:
pass
try:
return self.data[name]
except KeyError:
pass
raise AttributeError
以下会议将介绍:
In [108]: a = testAttrAccess()
In [109]: a.attr2
Out[109]: 'value2'
In [110]: a.__getattribute__('attr2')
Out[110]: 'value2'
In [111]: a.__getattr__('attr2')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/Users/laserson/temp/<ipython console> in <module>()
/Users/laserson/temp/<ipython console> in __getattribute__(self, name)
AttributeError:
In [112]: a.qwerty
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/Users/laserson/temp/<ipython console> in <module>()
/Users/laserson/temp/<ipython console> in __getattribute__(self, name)
AttributeError:
[108]中的:a=testAttrAccess()
在[109]中:a.attr2
Out[109]:“value2”
在[110]中:a.。\uuuuu getattribute\uuuuuu('attr2'))
Out[110]:“value2”
在[111]中:a.。\uuuu getattr\uuuuu('attr2'))
---------------------------------------------------------------------------
AttributeError回溯(最近一次呼叫上次)
/用户/laserson/temp/in()
/Users/laserson/temp/in\uuuu getattribute\uuuu(self,name)
属性错误:
在[112]中:a.qwerty
---------------------------------------------------------------------------
AttributeError回溯(最近一次呼叫上次)
/用户/laserson/temp/in()
/Users/laserson/temp/in\uuuu getattribute\uuuu(self,name)
属性错误:
噢,那为什么a.attr2
有效呢。也许不是这样。。。好问题a.attr2
的工作原理正是因为attr2
不存在,因此调用了\uu getattr\uuu
。默认的\uuuu getattribute\uuuu
显然不会调用\uuuuu getattr\uuuuuu
。感谢您澄清,我对自己进行了一分钟的事后猜测。我的印象是,无论何时,只要想覆盖属性访问以执行默认操作以外的操作,就应该只覆盖\uu getattr\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
,而不是\uuuuuuuuuuuuuuuuuu。这是正确的吗?您在上面提出的实施是否有任何隐藏的副作用?请参阅我提供的答案。我非常感谢您的评论。\uuuuu getattribute\uuuuuu
是为每个非魔法方法调用的(\uuuu add\uuuuuuuuu'、“\uu repr\uuuuuuuuuuuuu
等),因此将对性能产生巨大影响,并且完全不需要您想要的东西——使用\uuuu getattr\uuuuuuuuuuuu
的原始代码适合您想要做的事情。
In [108]: a = testAttrAccess()
In [109]: a.attr2
Out[109]: 'value2'
In [110]: a.__getattribute__('attr2')
Out[110]: 'value2'
In [111]: a.__getattr__('attr2')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/Users/laserson/temp/<ipython console> in <module>()
/Users/laserson/temp/<ipython console> in __getattribute__(self, name)
AttributeError:
In [112]: a.qwerty
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/Users/laserson/temp/<ipython console> in <module>()
/Users/laserson/temp/<ipython console> in __getattribute__(self, name)
AttributeError: