Python 属性支持继承吗?
在我的代码中,类Python 属性支持继承吗?,python,inheritance,properties,Python,Inheritance,Properties,在我的代码中,类A有一个属性,但类B不继承它。@property是否支持继承?还是我的错 class A(object): def __init__(self): self._x = 100 @property def x(self): return self._x @x.setter def x(self, v): self._x = v class B(A): @x.setter
A
有一个属性,但类B
不继承它。@property
是否支持继承?还是我的错
class A(object):
def __init__(self):
self._x = 100
@property
def x(self):
return self._x
@x.setter
def x(self, v):
self._x = v
class B(A):
@x.setter
def x(self, v):
self._x = v
错误消息如下所示:
Traceback (most recent call last):
File "test.py", line 9, in <module>
class B(A):
File "test.py", line 10, in B
@x.setter
NameError: name 'x' is not defined
回溯(最近一次呼叫最后一次):
文件“test.py”,第9行,在
B(A)类:
文件“test.py”,第10行,在B中
@x、 塞特
名称错误:未定义名称“x”
它只是不知道从哪里获得x
。您可以这样做:
class A(object):
def __init__(self):
self._x = 100
@property
def x(self):
return self._x
class B(A):
@A.x.setter
def x(self, v):
self._x = v
namererror
是因为x
不在全局范围内;它是在A
的类名称空间中定义的,因此您需要使用A.x
显式地访问它。这是一个相当常见的错误,请参见
但是,对于属性,它可能会变得稍微复杂一些。如果在B
中添加新的setter,则使用a.x.setter
没有问题,如中所示。但是,如果您重写现有的setter,您也将改变A
的行为。我怀疑这是你想要的行为
相反,在本例中,您需要使用的getter和新setter在子类中创建一个新属性。我认为这是实现这一目标的最简单方法,重复次数最少:
class B(A):
x = property(A.x.__get__) # new property with same getter
@x.setter # new setter on new property
def x(self, v):
...
注意属性的使用
没有@
语法糖,因为我没有用它来修饰新方法。如果您想从B
的setter访问A
的setter,可以使用super().x.\uu set\uuu(无论什么)
访问@A.x.setter
x
位于此处的命名空间A
下。您可以继承属性,但不能单独修改它。如果您继承x
并添加一个setter,则原始设置也将具有它。当然,您可以再次将属性定义为x
,以获得独立版本。因此x
在父级中是只读的,但在子级中是读写的?@klauds。当我测试下面的答案时,情况并非如此;我在尝试时得到了一个AttributeError
,例如A().x=1
,正如预期的那样。@jonrsharpe抱歉,在原始代码中,类A有@属性
和@setter
,而B只有@setter
,并且发生了错误。为了简化问题,我只是删除了A的@setter
,没有考虑太多,这是我的错,问题已经得到纠正。“当没有setter.A().x=1时,它将覆盖属性”-什么?您在Python2.x中尝试过这个吗?如果没有setter,属性是只读的,因此givesAttributeError:cannotsetattribute
@jornsharpe,你是对的。我将一个类更改为一个新样式的类,所以现在python2和python3都是一样的