有一类二维向量。
class vec(object):
def __init__(self, x=int(), y=int()):
self.x=x
self.y=y
需要用类声明操作方法(vec + vec, -, *, /, //, ...)
...
def __add__(self, vector):
return self.__class__(self.x + vector.x, self.y + vector.y)
...
它们的不同之处仅在于方法名称和两个相同的字符。从这个想法开始,我开始思考这些方法的构造函数。
一般来说,我所有的选择都与此没有什么不同:
...
def __math__(self, vector, operation):
return eval(f"self.__class__(self.x {operation} vector.x, self.y {operation} vector.y)")
def __init__(self, x=int(), self.y=int()):
...
for attr, operation in (("add", '+'), ):
setattr(self, f"__{attr}__", lambda self, vector: self.__math__(vector, operation)
...
在我看来,构造函数应该成功地正确添加了所有方法。在操作之前没有发生错误,但是在构造函数没有构造任何东西之后:
>>> vec(5, 5) + vec(2, 15)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'vec' and 'vec'
他的问题是什么?也许你知道如何让设计师变得更好?
有趣的测试:
class vec(object):
def __math__(self, vector, operation):
return eval(f"self.__class__(self.x {operation} vector.x, self.y {operation} vector.y)")
def __init__(self, x=int(), y=int()):
self.x=x
self.y=y
for name, operation in (("add", '+'), ):
setattr(self, f"__{name}__", lambda self, vector: self.__math__(vector, operation))
if __name__ != "__main__":
try:
vec(100, 500) + vec(900, 500)
except TypeError:
print("Failed\n", dir(vec()), '\n\n')
在终端中导入带有此测试的库。结果:
>>> import muz
Failed
['__add__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__math__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'x', 'y']
>>> muz.vec().__add__(muz.vec(7, 6), muz.vec(5, 2))
<muz.vec object at 0x00E3BB50>
即注意“失败”:加法运算vec + vec 是不可能的。接下来我们打印向量类的属性列表。注意属性列表的第一个元素:__add__
可用。看起来,你的问题是什么,该死的?我设法只以某种破碎的方式调用__add__
它(从底部开始的第二行)。
对象方法必须在对象创建阶段(方法
__new__
)创建。__init__
同样已经进行了初始化。