例如:
class Example:
def __init__(self):
self.v = 0
@property
def value(self):
return self.v
@value.setter
def value(self, v):
self.v = v
class SubExample(Example):
pass
是否可以在SubExample中仅将getter重写为值?
答案 0 :(得分:4)
你可以这样做
class DoubleExample(Example):
@Example.value.getter
def value(self):
return self.v * 2
o = Example()
o.value = 1
print o.value # prints "1"
p = DoubleExample()
p.value = 1
print p.value # prints "2"
但是,这仅在Example
是新样式类(class Example(object):
)而不是旧样式类(class Example:
)时才有效,就像在示例代码中一样。 / p>
警告: Thomas在评论中指出,如果您使用多重继承(class Foo(Bar, Baz)
),此方法可能无法按预期运行。
答案 1 :(得分:3)
无法在子类中覆盖属性的getter,no。该属性是一个存在于类中的对象,它包含对您提供的函数的引用 - 如果稍后重新定义这些函数的名称,它将根本不会影响该属性。
你可以做的是让你的属性调用的函数执行间接调用,如下所示:
class Example(object):
def __init__(self):
self.v = 0
@property
def v(self):
return self._v_getter()
@v.setter
def v(self, value):
return self._v_setter(value)
def _v_setter(self, value):
self._v = value
class SubExample(Example):
def _v_getter(self):
return 5
>>> se = SubExample()
>>> se.v
5
>>> se._v
0
>>> se.v = 10
>>> se.v
5
>>> se._v
10
或者,您可以通过简单地定义新属性来重新定义子类中的整个属性。但是,您无法方便地访问父类中定义的函数或属性,并且面对多重继承时做正确的事情很困难。
答案 2 :(得分:0)
您的问题之前已得到解答:
http://code.activestate.com/recipes/408713-late-binding-properties-allowing-subclasses-to-ove/ http://stackoverflow.com/questions/3393534/python-property-and-method-override-issue-why-subclass-property-still-calls-the
本质上,不必直接使用property
,而是必须推迟调用getter,以便它在第一次定义属性时访问子类中定义的而不是超类中定义的那个。这可以通过lambda
:
class Test(object):
def __init__(self):
self.v = 0
def _value(self):
return self.v
def _value_setter(self, v):
self.v = v
value = property(lambda self: self._value(), lambda self, v: self._value_setter(v))
class Test2(Test):
def _value(self):
return self.v + 1
a = Test()
a.value = 2
print a.value # 2
b = Test2()
b.value = 2
print b.value # 4