在python类属性中访问'super()'
我正在学习python的继承,遇到了一个我不太理解的行为。下面是一个简单的工作示例:在python类属性中访问'super()',python,inheritance,python-decorators,Python,Inheritance,Python Decorators,我正在学习python的继承,遇到了一个我不太理解的行为。下面是一个简单的工作示例: class Test(): def meth1(自身): 打印('1') 返回super().a#调用随机不存在属性;错误(如预期的那样) @财产 def prop1(自身): 打印('访问prop1') 返回super().a#调用随机不存在属性;没有错误? def _ugetattr _;(self,name): 打印('getattr'+名称) 测试=测试() 调用.meth1()按预期失败 In [
class Test():
def meth1(自身):
打印('1')
返回super().a#调用随机不存在属性;错误(如预期的那样)
@财产
def prop1(自身):
打印('访问prop1')
返回super().a#调用随机不存在属性;没有错误?
def _ugetattr _;(self,name):
打印('getattr'+名称)
测试=测试()
调用.meth1()
按预期失败
In [1]: test.meth1()
accessing meth1
Traceback (most recent call last):
File "<ipython-input-160-4a0675c95211>", line 1, in <module>
test.meth1()
File "<ipython-input-159-1401fb9a0e13>", line 5, in meth1
return super().a #calling random nonexisting attribute; error (as expected)
AttributeError: 'super' object has no attribute 'a'
…我不明白。该属性似乎被调用了两次,一次是“正常”调用,一次是通过\uuu getattr\uuu
调用
一些意见:
- 我想这与
装饰器有关属性
- 属性
似乎永远无法访问.a
- 如果我将
中的prop1
行替换为类似return super().a
的内容,则永远不会调用return 5
方法\u getattr\u
- 如果我实际使
从具有属性Test
的类继承,则其值将从a
返回,而不是从Test.meth1()
返回Test.prop1
super()
组合的有用信息
非常感谢,TLDR:
meth1
在不涉及\uu getattr\uuu
的情况下,在查找后引发属性错误prop1
在查找过程中引发AttributeError
,触发返回到\uuuu getattr\uuuuu
的回退,该回退成功返回None
>test.prop1#AttributeError在查找过程中发生在此处
访问prop1
getattr prop1
>>>meth=test.meth1#AttributeError在查找过程中发生*不是*
>>>meth()#AttributeError发生在此处*在*查找之后
...
AttributeError:“超级”对象没有属性“a”
\uuuu getattr\uuuu
方法仅在“未找到属性”时调用,换句话说,在访问时引发AttributeError
。当属性直接引发错误时,也会发生相同的行为:
class Test():
@财产
def prop1(自身):
打印('访问prop1')
raise AttributeError替换'super().a`
def _ugetattr _;(self,name):
打印('getattr'+名称)
测试=测试()
test.prop1#<显式引发AttributeError
#访问prop1
#getattr prop1
test.prop2#<隐式引发AttributeError
#getattr prop2
AttributeError
不会显示它是来自缺少的prop1
属性还是某个嵌套的内部属性(例如,super().a
)。因此,两者都会触发回退到\uu getattr\uu
这是的预期行为
当默认属性访问失败且出现AttributeError时调用(由于名称不是实例属性或类树中的属性,因此,\uuuuuGetAttribute\uuuuuuuuuuuuuuoRor()
引发一个AttributeError
;或者名称属性的\uuuuuGet\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuoCode>引发AttributeError)
当属性无法生成值时,它允许属性回退到常规查找机制。在这种情况下,属性
似乎正在抑制属性错误
。这不是关于super
;属性中的显式raise AttributeError
也被静默。我是否理解正确?我要拟人化。要执行meth1
,首先需要在对象内部字典中查找它。它被找到并加载到内存中。“Python知道此对象上存在此方法”。然后抛出一个AttributeError
,但这不会引起混淆,这可能是因为对象上缺少属性,所以我们不会进入\uuuuuuuGetAttr\uuuuuuuuu
。(1/2)与属性不同prop1
“模拟”一个简单的有值属性的存在(就好像它是self.prop1
),显然,属性prop1
只有在对其值进行无误评估后才假定存在。由于没有发生这种情况,python假定AttributeError
表示它不存在,并使用\uuuu getattr\uuuuu
检查是否定义了回退,即返回None
。(2/2)@ElRudi是的,就是这样。查找方法和调用方法是两件不同的事情。您可以将test.meth1
分为a)tmeth1=test.meth1()
和b)tmeth1()
。值得注意的是,a)进行查找(可能包括\uu getattr\uuu
),但b)会引发属性错误。属性是作为查找的一部分调用的,因此只有A)和AttributeError
。非常好,非常感谢。这是否意味着这种行为一般不适用于装饰师?它是否仅仅因为执行了它所修饰的函数就适用于属性
。您可以通过调用语法构建一个属性
,或者插入一个预构建的属性,其行为在这里也一样。重要的部分是对象@属性+函数构造什么;即在\uuuuu get\uuuu
过程中引发错误的内容(在这种情况下,通过调用\uuuuu get\uuuu
函数)。比较@classmethod
,它不会抑制错误。
In [2]: test.prop1
accessing prop1
getattr prop1