Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.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_Inheritance_Properties - Fatal编程技术网

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,属性是只读的,因此gives
AttributeError:cannotsetattribute
@jornsharpe,你是对的。我将一个类更改为一个新样式的类,所以现在python2和python3都是一样的