优雅地重载Python类属性的方法
考虑一个基类:
class A(object):
def __init__(self, x):
self._x = x
def get_x(self):
#...
return self._x
def set_x(self, x):
#...
self._x = x
x = property(get_x, set_x)
还有一个派生类:
class B(A):
def set_x(self, x):
#...
self._x = x**2
x = property(A.get_x, set_x)
有没有一种优雅的方法可以在类 B
中重载 set_x()
,而不需要重新声明它和属性 x
?谢谢。
2 个回答
3
增加一个额外的间接层(也就是说,使用一个钩子):
class A(object):
def __init__(self, x):
self._x = x
# Using a _get_hook is not strictly necessary for your problem...
def _get_hook(self):
return self._x
def get_x(self):
return self._get_hook()
# By delegating `set_x` behavior to `_set_hook`, you make it possible
# to override `_set_hook` behavior in subclass B.
def _set_hook(self, x):
self._x=x
def set_x(self, x):
self._set_hook(x)
x = property(get_x, set_x)
class B(A):
def _set_hook(self, x):
print('got here!')
self._x = x**2
b=B(5)
b.x=10
# got here!
print(b.x)
# 100
对于现代版本的Python,你还可以使用@property装饰器:
class A(object):
@property
def x(self):
return self._get_hook()
@x.setter
def x(self, x):
self._set_hook(x)
2
试试这个:
class A(object):
def __init__(self):
self._x = 0
def get_x(self):
#...
return self._x
def set_x(self, x):
#...
self._x = x
x = property(get_x, lambda self,x : self.set_x(x))
class B(A):
def set_x(self, x):
#...
self._x = x**2
使用 lambda 这个东西可以让 set_x 函数变得更灵活。