【发布时间】:2021-06-05 08:05:51
【问题描述】:
Python @property inheritance the right way 解释了如何调用父 setter。
class Number:
def __init__(self):
self._value = None
@property
def value(self):
assert self._value is not None
return self._value
@value.setter
def value(self, new_value):
self._value = new_value
class Integer(Number):
@property
def value(self):
return super().value
@value.setter
def value(self, new_value):
_value = int(new_value)
super(Integer, type(self)).value.fset(self, _value) # <----- OK with using type(self)
# super(Integer, self).value.fset(self, _value) # <----- Assert error with self
i = Integer()
i.value = 1 # cause assertion error with "super(Integer, self)"
print(i.value)
问题
使用 super(Integer, type(self)).value.fset(self, _value) ,i.value = 1 按预期调用设置器。
对于super(Integer, self).value.fset(self, _value),i.value = 1 调用的是getter 而不是setter,因此会导致断言错误。
AssertionError Traceback (most recent call last)
<ipython-input-8-2c57a07c128d> in <module>
35
36 i = Integer()
---> 37 i.value = 1
38 print(i.value)
<ipython-input-8-2c57a07c128d> in value(self, new_value)
32 _value = int(new_value)
33 #super(Integer, type(self)).value.fset(self, _value)
---> 34 super(Integer, self).value.fset(self, _value)
35
36 i = Integer()
<ipython-input-8-2c57a07c128d> in value(self)
10 @property
11 def value(self):
---> 12 assert self._value is not None
13 return self._value
问题
请帮助理解为什么super(Integer, self).value.fset(self, _value) 会使用getter 而不是setter,尽管调用fset。阅读文档和文章,在我看来传递对象 self 而不是类型/类 type(self) 是访问绑定到实例本身的方法的正确方法,但它不起作用。
super([type[, object-or-type]])
对象或类型决定方法解析顺序 搜索。搜索从类型之后的类开始。
例如,如果 mro 的 object-or-type 是 D -> B -> C -> A -> object 且 type 的值为 B,则 super() 搜索 C -> A -> 对象。
object-or-type 的 mro 属性列出了方法 getattr() 和 super() 使用的分辨率搜索顺序。这 属性是动态的,并且可以在继承层次结构时更改 已更新。
Supercharge Your Classes With Python super()
在 Python 3 中,super(Square, self) 调用等价于 无参数 super() 调用。第一个参数指的是子类 Square,而第二个参数是指一个 Square 对象,在 这个案子,是自己。您也可以使用其他类调用 super():
def surface_area(self): face_area = super(Square, self).area() return face_area * 6 def volume(self): face_area = super(Square, self).area() return face_area * self.length第二个参数呢?请记住,这是一个对象 用作第一个参数的类的实例。例如, isinstance(Cube, Square) 必须返回 True。
通过包含一个实例化的对象,super() 返回一个绑定的方法:a 绑定到对象的方法,它赋予该方法 对象的上下文,例如任何实例属性。如果这个参数是 不包含,返回的方法只是一个函数,无关联 带有对象的上下文。
【问题讨论】:
标签: python super python-class