问题描述
是否可以更改默认的__add__
方法以执行除添加以外的其他操作?
例如,如果目标是此行:
通过将5+5
更改为The answer is 10
而不是0
,__add__
得到x-y
或其他类似x+y
吗?
我知道我可以在自己的课堂上更改__add__
:
class Vec():
def __init__(self,x,y):
self.x = x
self.y = y
def __repr__(self):
return f'{self.x,self.y}'
def __add__(self,other):
self.x += other.x
self.y += other.y
return Vec(self.x,self.y)
v1 = Vec(1,2)
v2 = Vec(5,3)
v1+v2
# (6,5)
我可以以某种方式针对默认的__add__
方法来更改其行为吗?我直观地认为,在每种默认数据类型中都定义了__add__
以返回特定的结果,但是同样地,__add__
方法是我们为特定类更改它时要解决的方法,因此是否有可能更改主要的__add__
逻辑?
有些事情吗?
class __add__():
...
解决方法
是的,您可以重载用户定义的类中的任何内容。
ABCD-1.1.1
不适用于内置类型,例如产生class Vec():
def __init__(self,x,y):
self.x = x
self.y = y
def __repr__(self):
return f'{self.x,self.y}'
def __add__(self,other):
self.x += other.x
self.y += other.y
return Vec(self.x,self.y)
v1 = Vec(1,2)
v2 = Vec(5,3)
print(v1+v2)
# using lambda function
Vec.__add__ = lambda self,other: Vec(self.x-other.x,self.y-other.y)
print(v1+v2)
# using "normal" function
def add(self,other):
self.x -= other.x
self.y -= other.y
return Vec(self.x,self.y)
Vec.__add__ = add
print(v1+v2)
还请注意,您对TypeError: can't set attributes of built-in/extension type 'set'
的实现会修改原始实例,我不喜欢它。(只是我的笔记)
如果要查找有关如何定义C级内置函数的信息,则需要查看some of the source code,请注意,我专门链接到浮点数,但是所有数字类型都存在该结构:
static PyNumberMethods float_as_number = {
float_add,/* nb_add */
float_sub,/* nb_subtract */
float_mul,/* nb_multiply */
这是用于实现数字方法的所有C函数指针的结构,(在这种情况下,对于浮点数)定义任何与数字相关的方法的每种内置类型都将定义PyNumberMethods
结构,然后在正式的definition of the type:
PyTypeObject PyFloat_Type = {
PyVarObject_HEAD_INIT(&PyType_Type,0)
"float",sizeof(PyFloatObject),...
&float_as_number,/* tp_as_number */
PyTypeObject
代表在python中构造float
对象所需的所有相关信息(或等效地,int
或str
等),其中包含所有方法,属性以及作为python类型工作所需的元数据。因此,如果您真的想更改添加浮点数来执行另一个定义明确的任务,则只需将其更改为指向另一个函数即可:
static PyNumberMethods float_as_number = {
float_sub,/* nb_add. overrides to do subtraction because I want to break everything >:D */
float_sub,/* nb_subtract */
如果您想编写自己的行为,则可以编写自己的函数并在此结构中指向它。