问题描述
|
例如:
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重写为value?
解决方法
你可以这样
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:
)时才有效,如示例代码中所示。
警告:Thomas在注释中指出,如果您正在使用多重继承(class Foo(Bar,Baz)
),则此方法可能无法达到预期的效果。
, 不可能在子类中覆盖属性的getter,否。该属性是一个存在于类中的对象,并且拥有对您赋予它的函数的引用-如果以后重新定义这些函数的名称,则它根本不会影响该属性。
您可以做的是让属性调用函数执行间接调用,如下所示:
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
另外,您可以通过简单地定义新属性来在子类中重新定义整个属性。但是,您将无法方便地访问父类中定义的函数或属性,面对多重继承做正确的事情很困难。
, 您的问题已得到回答:
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
本质上,您不必延迟直接调用ѭ7,而必须延迟调用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