Python 3 在加法运算中翻转参数的方法
Python 3 method to flip arguments in an addition operation
我有一个 class 添加两个点(其中一个是点类型,另一个是元组或列表 -- 见代码)。我的问题是我的 add 方法只有在我按特定顺序输入数字时才有效。我需要创建第二种方法(根据此分配中的规则),它只包含一行调用 add 方法和 returns 结果,并且可以在数据中找到文档模型。
class Point():
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __str__(self):
return ("X = " + str(self.x) + "\nY = " + str(self.y))
def __add__(self, other):
if isinstance(other,list) or isinstance(other,tuple):
newX = other[0] + self.x
newY = other[1] + self.y
return(Point(newX,newY))
else:
newX = self.x + other
newY = self.y + other
return(Point(newX,newY))
p = Point(5,10)
print(p + [3.5,6])
print([3.5,6] + p)
我搜索了数据模型,我只能认为 reversed 或带有 getattr 的东西会起作用,但我没有想法如何实施,或者我是否走在正确的轨道上。请帮忙!
您应该在 class 中添加 __radd__()
:
def __radd__(self, *args, **kwargs):
return self.__add__(*args, **kwargs)
这实际上会做一个 __add__()
因为在这种情况下它确实是一样的。
但是你可以考虑让 class 表现得像一个列表,像这样:
class Point():
def __init__(self, x=0, y=0):
self.x = x
self.y = y
self._list = [self.x, self.y]
def __str__(self):
return ("X = " + str(self.x) + "\nY = " + str(self.y))
def __repr__(self):
return str(self._list)
def __iter__(self):
for elem in self._list:
yield elem
def __getitem__(self, i):
return self._list(i)
def __len__(self):
return len(self._list)
def __delitem__(self, i):
#not sure if you really want this
del self._list[i]
def __setitem__(self, i, val):
#not sure if you really want this
self._list[i] = val
def __add__(self, other):
#this code could be optimized
#using your original code for this example
if isinstance(other,list) or isinstance(other,tuple):
newX = other[0] + self.x
newY = other[1] + self.y
else:
newX = self.x + other
newY = self.y + other
#returning a list
return [newX, newY]
def __radd__(self, *args, **kwargs):
return self.__add__(*args, **kwargs)
p = Point(5,10)
print(p)
print(p + [3.5,6])
print([3.5,6] + p)
输出:
[5, 10]
[8.5, 16]
[8.5, 16]
[edit] 如果你决定让它表现得像 list
,你也可以 subclass list
,例如:
class Point(list):
def __init__(self, x=0, y=0):
super(Point, self).__init__([x, y])
def __add__(self, other):
if isinstance(other, (list, tuple)):
return [sum(i) for i in zip(self, other)]
elif isinstance(other, (int, float)):
return [i + other for i in self]
else:
return self
def __radd__(self, *args, **kwargs):
return self.__add__(*args, **kwargs)
#you probably want a __sub__
def __sub__(self, other):
if isinstance(other, (list, tuple)):
return [i - j for i, j in zip(self, other)]
elif isinstance(other, (int, float)):
return [i - other for i in self]
else:
return self
#and an __rsub__
def __rsub__(self, other):
if isinstance(other, (list, tuple)):
return [i - j for i, j in zip(other, self)]
elif isinstance(other, (int, float)):
return [other - i for i in self]
else:
return self
#take away functions you do not want
def pop(*args, **kwargs): pass
def sort(*args, **kwargs): pass
def append(*args, **kwargs): pass
def extend(*args, **kwargs): pass
def insert(*args, **kwargs): pass
def remove(*args, **kwargs): pass
def reverse(*args, **kwargs): pass
p = Point(5,10)
tests = [[3.5, 6], (5,4), 1.1, 'wrong string', [1, 2, 3]]
for test in tests:
print(p + test)
print(test + p)
for test in tests:
print(p - test)
print(test - p)
p.append(4)
print(p)
输出:
[8.5, 16]
[8.5, 16]
[10, 14]
[10, 14]
[6.1, 11.1]
[6.1, 11.1]
[5, 10]
[5, 10]
[6, 12]
[6, 12]
[1.5, 4]
[-1.5, -4]
[0, 6]
[0, -6]
[3.9, 8.9]
[-3.9, -8.9]
[5, 10]
[5, 10]
[4, 8]
[-4, -8]
[5, 10]
我有一个 class 添加两个点(其中一个是点类型,另一个是元组或列表 -- 见代码)。我的问题是我的 add 方法只有在我按特定顺序输入数字时才有效。我需要创建第二种方法(根据此分配中的规则),它只包含一行调用 add 方法和 returns 结果,并且可以在数据中找到文档模型。
class Point():
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __str__(self):
return ("X = " + str(self.x) + "\nY = " + str(self.y))
def __add__(self, other):
if isinstance(other,list) or isinstance(other,tuple):
newX = other[0] + self.x
newY = other[1] + self.y
return(Point(newX,newY))
else:
newX = self.x + other
newY = self.y + other
return(Point(newX,newY))
p = Point(5,10)
print(p + [3.5,6])
print([3.5,6] + p)
我搜索了数据模型,我只能认为 reversed 或带有 getattr 的东西会起作用,但我没有想法如何实施,或者我是否走在正确的轨道上。请帮忙!
您应该在 class 中添加 __radd__()
:
def __radd__(self, *args, **kwargs):
return self.__add__(*args, **kwargs)
这实际上会做一个 __add__()
因为在这种情况下它确实是一样的。
但是你可以考虑让 class 表现得像一个列表,像这样:
class Point():
def __init__(self, x=0, y=0):
self.x = x
self.y = y
self._list = [self.x, self.y]
def __str__(self):
return ("X = " + str(self.x) + "\nY = " + str(self.y))
def __repr__(self):
return str(self._list)
def __iter__(self):
for elem in self._list:
yield elem
def __getitem__(self, i):
return self._list(i)
def __len__(self):
return len(self._list)
def __delitem__(self, i):
#not sure if you really want this
del self._list[i]
def __setitem__(self, i, val):
#not sure if you really want this
self._list[i] = val
def __add__(self, other):
#this code could be optimized
#using your original code for this example
if isinstance(other,list) or isinstance(other,tuple):
newX = other[0] + self.x
newY = other[1] + self.y
else:
newX = self.x + other
newY = self.y + other
#returning a list
return [newX, newY]
def __radd__(self, *args, **kwargs):
return self.__add__(*args, **kwargs)
p = Point(5,10)
print(p)
print(p + [3.5,6])
print([3.5,6] + p)
输出:
[5, 10]
[8.5, 16]
[8.5, 16]
[edit] 如果你决定让它表现得像 list
,你也可以 subclass list
,例如:
class Point(list):
def __init__(self, x=0, y=0):
super(Point, self).__init__([x, y])
def __add__(self, other):
if isinstance(other, (list, tuple)):
return [sum(i) for i in zip(self, other)]
elif isinstance(other, (int, float)):
return [i + other for i in self]
else:
return self
def __radd__(self, *args, **kwargs):
return self.__add__(*args, **kwargs)
#you probably want a __sub__
def __sub__(self, other):
if isinstance(other, (list, tuple)):
return [i - j for i, j in zip(self, other)]
elif isinstance(other, (int, float)):
return [i - other for i in self]
else:
return self
#and an __rsub__
def __rsub__(self, other):
if isinstance(other, (list, tuple)):
return [i - j for i, j in zip(other, self)]
elif isinstance(other, (int, float)):
return [other - i for i in self]
else:
return self
#take away functions you do not want
def pop(*args, **kwargs): pass
def sort(*args, **kwargs): pass
def append(*args, **kwargs): pass
def extend(*args, **kwargs): pass
def insert(*args, **kwargs): pass
def remove(*args, **kwargs): pass
def reverse(*args, **kwargs): pass
p = Point(5,10)
tests = [[3.5, 6], (5,4), 1.1, 'wrong string', [1, 2, 3]]
for test in tests:
print(p + test)
print(test + p)
for test in tests:
print(p - test)
print(test - p)
p.append(4)
print(p)
输出:
[8.5, 16]
[8.5, 16]
[10, 14]
[10, 14]
[6.1, 11.1]
[6.1, 11.1]
[5, 10]
[5, 10]
[6, 12]
[6, 12]
[1.5, 4]
[-1.5, -4]
[0, 6]
[0, -6]
[3.9, 8.9]
[-3.9, -8.9]
[5, 10]
[5, 10]
[4, 8]
[-4, -8]
[5, 10]