Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python属性访问错误_Python_Oop_Attributes - Fatal编程技术网

Python属性访问错误

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

我试图在类(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:
            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: