简体   繁体   English

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

[英]Can I change the default __add__ method in Python?

Is it possible to change the default __add__ method to do something else than just add?是否可以更改默认的__add__方法来执行除添加之外的其他操作?

For example, if the goal is with this line: 5+5 get The answer is 10 or anything else like 0 by changing __add__ to be xy instead of x+y ?例如,如果目标是这一行: 5+5 get The answer is 10 or anything else like 0 by changing __add__ to be xy instead of x+y ?

I know I can change __add__ in my own classes:我知道我可以在自己的课程中更改__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)

Can I somehow target the default __add__ method to change its behaviour?我可以以某种方式针对默认的__add__方法来改变它的行为吗? I intuitively think that __add__ is defined in each default data type to return specific results, but then again, the __add__ method is what we address when changing it for a specific class, so, is it possible to change the main __add__ logic?我直觉地认为__add__是在每个默认数据类型中定义的,以返回特定的结果,但话又说回来, __add__方法是我们在为特定的 class 更改它时要解决的问题,那么,是否可以更改主要的__add__逻辑?

Something along these lines?这些方面的东西?

class __add__():
    ...

Yes, you can overload whatever in user defined classes.是的,您可以重载用户定义类中的任何内容。

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)

Will not work for built-in types, eg resulting in TypeError: can't set attributes of built-in/extension type 'set'不适用于内置类型,例如导致TypeError: can't set attributes of built-in/extension type 'set'

Also please note that your implementation of __add__ modifies the original instance, which I don't like.. (just my note)另请注意,您对__add__的实现修改了原始实例,我不喜欢这样……(只是我的笔记)

If you are looking for information about how the C level built-ins are defined you would want to look at some of the source code , note that I'm linking specifically to floats but the structure exists for all number types:如果您正在寻找有关如何定义 C 关卡内置函数的信息,您可能希望查看一些源代码,请注意我专门链接到浮点数,但该结构适用于所有数字类型:

static PyNumberMethods float_as_number = {
    float_add,          /* nb_add */
    float_sub,          /* nb_subtract */
    float_mul,          /* nb_multiply */

this is the structure for all the C function pointers that implement number methods, (for floats in this case) each builtin type that defines any number related methods will define a PyNumberMethods structure, this is then used in the formal definition of the type:这是实现数字方法的所有 C function 指针的结构,(在这种情况下对于浮点数)定义任何数字相关方法的每个内置类型都将定义一个PyNumberMethods结构,然后在类型的正式定义中使用:

PyTypeObject PyFloat_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "float",
    sizeof(PyFloatObject),
   
    ...
        
    &float_as_number,                           /* tp_as_number */

the PyTypeObject represents all the relevant information needed to construct the float object in python, (or equivalently, int or str etc.) containing all the methods, attributes, and necessary meta-data to work as a python type. PyTypeObject表示在 python 中构造float object 所需的所有相关信息(或等效的intstr等),其中包含所有方法、属性和必要的元数据,以作为 python 类型工作。 So if you really wanted to change adding floats to instead do another well defined task you'd just change it to point to the other function:因此,如果您真的想更改添加浮点数以代替执行另一个定义明确的任务,您只需将其更改为指向另一个 function:

static PyNumberMethods float_as_number = {
    float_sub,          /* nb_add.  overrides to do subtraction because I want to break everything >:D */
    float_sub,          /* nb_subtract */

If you wanted to write your own behaviour you could write your own function and point to it in this structure instead.如果你想写你自己的行为,你可以写你自己的 function 并在这个结构中指向它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM