有关 Python3 的 重载运算符 与 引用问题
假设我有这样一个需求:
给定三点:A、B、C;其中A与B坐标已知,C点坐标 = A点 + B点当A点坐标发生变化时,C点也应该发生变化。
我是这样写的:
class Point: def __init__(self, coordinate:tuple):
self.x = coordinate[0]
self.y = coordinate[1]
def __repr__(self):
return "(%.2f, %.2f)" % (self.x, self.y)
def __add__(self, other:Point):
if isinstance(other, Point):
x = self.x + other.x
y = self.y + other.y
return Point(coordinate=(x,y))
然后定义A与B的坐标 以及C的关系:
A = Point((1,1))B = Point((4,1))
C = A + B
此时C点的坐标应该为:(5,2)
但我进行如下操作后
A.x=5
C点的坐标并没有发生变化...原因我知道,因为__add__给C返回的是一个新的Point对象。
我想请教各位,如何设计,才能让C点的坐标根据A点/B点的坐标变化而变化呢?
回答:
把C和AB关联起来就可以了
class Point: def __init__(self, coordinate:tuple,point = None,point2 = None):
self._point = point
self._point2 = point2
if self._point is None or self._point2 is None:
self._point,self._point2 = coordinate
def _simple(self):
return not isinstance(self._point, Point)
def _reset(self,x,y):
self._point = x
self._point2 = y
def x(self,vx = None):
if vx is not None: self._reset(vx,self.y())
return self._point if self._simple() else self._point.x() + self._point2.x()
def y(self,vy = None):
if vy is not None: self._reset(self.x(),vy)
return self._point2 if self._simple() else self._point.y() + self._point2.y()
def __add__(self, other):
return Point(None, self, other) if isinstance(other, Point) else self
def __repr__(self):
return "(%.2f, %.2f)" % (self.x(), self.y())
A = Point((1,1))
B = Point((4,1))
C = A + B
print(C) #(5,2)
A.x(5)
print(C) #(9,2)
回答:
class Point: def __init__(self, coordinate=None, parent_points=None):
if coordinate is None and parent_points is None:
raise ValueError("coordinate and parent_points cannot be both None")
self.parent_points = parent_points
self.coordinate = coordinate
def __getattr__(self, item):
if item not in ('x', 'y'):
raise AttributeError("Point only has x and y")
if self.parent_points:
return sum(i.x if item == 'x' else i.y for i in self.parent_points)
else:
return self.coordinate[0 if item == 'x' else 1]
@property
def x(self):
return self.__getattr__('x')
@x.setter
def x(self, n):
if self.coordinate is None:
raise Exception("this point is associated with other point, so it cannot be modified")
self.coordinate[0] = n
@property
def y(self):
return self.__getattr__('y')
@y.setter
def y(self, n):
if self.coordinate is None:
raise Exception("this point is associated with other point, so it cannot be modified")
self.coordinate[1] = n
def __repr__(self):
return "(%.2f, %.2f)" % (self.x, self.y)
def __add__(self, other):
return Point(parent_points=[self, other])
if __name__ == '__main__':
a = Point([1, 1])
b = Point([4, 1])
c = a + b
d = a + b + c
print("Now c is {}".format(c))
print("Now d is {}".format(d))
a.x = 5
b.y = 2
print("Now c is {}".format(c))
print("Now d is {}".format(d))
以上是 有关 Python3 的 重载运算符 与 引用问题 的全部内容, 来源链接: utcz.com/a/160167.html