我可以在Python中更改默认的__add__方法吗?

问题描述

是否可以更改认的__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对象所需的所有相关信息(或等效地,intstr等),其中包含所有方法,属性以及作为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 */

如果您想编写自己的行为,则可以编写自己的函数并在此结构中指向它。