[英]Python: Unexpected behaviour when overriding properties
I would like to inherit from a class containing a property x
, and then make this property read-only in the child class by overriding the setter. 我想从包含属性
x
的类继承,然后通过覆盖setter使此属性在子类中为只读。 This does not work if __init__
in the parent class uses the original setter. 如果父类中的
__init__
使用原始的setter,则此方法不起作用。 Consider the following code. 考虑以下代码。
class Parent:
def __init__(self, x=1):
# I want the following line to use the setter defined in the Parent
# class, even when __init__ is called from Child using super.
self.x = x
# Other initialization of Parent goes here.
@property
def x(self):
return self._x
@x.setter
def x(self, value):
"""Check that x is non-negative."""
if value < 0:
raise ValueError("x must be non-negative.")
self._x = value
class Child(Parent):
def __init__(self):
super().__init__() # Need this for initialization.
@property
def y(self):
return self._y
@y.setter
def y(self, value):
"""x can only be written to implicitly by setting y."""
self._y = value
self._x = abs(value)
@property
def x(self):
return self._x
@x.setter
def x(self, value):
raise AttributeError("Illegal access to x")
If I now try to instantiate Child
, I get AttributeError: Illegal access to x
because when the line self.x = x
is called, the x
setter of Child
is called instead of the x
setter of Parent
. 如果我现在尝试实例
Child
,我得到AttributeError: Illegal access to x
,因为当行self.x = x
被调用时, x
的二传手Child
被调用,而不是x
的二传手Parent
。 How can I get it to use the setter of Parent
in a Pythonic way? 如何以Python方式使用
Parent
的二传手?
To be clear, when self.x = ...
appears in a method of Parent
, it should always make use of the x
setter in Parent
, and when self.x = ...
appears in a method of Child
, it should always make use of the x
setter in Child
, and thus raise an exception. 需要明确的是,当
self.x = ...
出现在Parent
方法中时,它应始终使用Parent
中的x
setter;当self.x = ...
出现在Child
方法中时,则应始终使用x
setter利用Child
中的x
setter,从而引发异常。
I managed to solve the problem myself by swapping out 我设法通过换出解决了自己的问题
self.x = x
in Parent.__init__
with 在
Parent.__init__
与
Parent.x.fset(self, x)
I can also get rid of 我也可以摆脱
@property
def x(self):
return self._x
in Child
if instead of @x.setter
, I use @Parent.x.setter
. 在
Child
如果代替@x.setter
,我用@Parent.x.setter
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.