Skip to content

Python 运算符重载

运算符重载指:对自定义类实现特殊方法(魔术方法)后,+< 等运算符在作用于该类的实例时,会调用你定义的行为。这与内置类型上运算符的「多种含义」是同一机制——例如 +int 做加法,对 str 做拼接,对 list 做合并。

python
print(5 + 5)
print("Safa" + "Mulani")
print(10 * 10)
print("Safa" * 4)

输出:

text
10
SafaMulani
100
SafaSafaSafaSafa

自定义类通过 __add____mul__ 等参与同一套规则。与 OOP 总览见 面向对象编程类与对象

特殊方法与运算符的对应关系

以双下划线包裹的名字(如 __init____add__)由解释器在特定语法下调用;__init__ 在构造实例时使用,不属于「全局函数」。

若左操作数的方法返回 NotImplemented,Python 会尝试交换操作数或回退到其它实现;对不支持的类型应返回 NotImplemented,而不是随意抛错(进阶约定)。

常见二元算术

运算符特殊方法
+__add__(self, other)
-__sub__(self, other)
*__mul__(self, other)
/__truediv__(self, other)
//__floordiv__(self, other)
%__mod__(self, other)
**__pow__(self, other[, mod])

另有 __radd__「反向」 方法,在左操作数不支持时由右操作数尝试。

常见比较运算

运算符特殊方法
<__lt__(self, other)
>__gt__(self, other)
<=__le__(self, other)
>=__ge__(self, other)
==__eq__(self, other)
!=__ne__(self, other)

比较方法宜返回 bool(或 NotImplemented),以便 sortedif 等正常工作。若返回字符串,会破坏常见协议。

增强赋值(Python 3)

运算符特殊方法
+=__iadd__(self, other)
-=__isub__(self, other)
*=__imul__(self, other)
/=__itruediv__(self, other)
//=__ifloordiv__(self, other)
%=__imod__(self, other)
**=__ipow__(self, other[, mod])

Python 2 的 __idiv__ 在 Python 3 中不存在;普通除法用 __truediv__,增强赋值用 __itruediv__

一元运算

运算符特殊方法
-x__neg__(self)
+x__pos__(self)
~x__invert__(self)

注意:一元方法的参数只有 self,没有 other

示例:重载 +__add__

python
class X:
    def __init__(self, x):
        self.x = x

    def __add__(self, other):
        return X(self.x + other.x)


a = X(5)
b = X(5)
print((a + b).x)

u = X("Safa")
v = X("Mulani")
print((u + v).x)

输出:

text
10
SafaMulani

示例:比较运算(返回 bool

python
class X:
    def __init__(self, x):
        self.x = x

    def __lt__(self, other):
        return self.x < other.x

    def __eq__(self, other):
        return self.x == other.x


p = X(2)
q = X(3)
print(p < q)

r = X(4)
s = X(4)
print(r == s)
print(p == q)

输出:

text
True
True
False

示例:Animal__str__

python
class Animal:
    def __init__(self, age):
        self.__age = age

    def getage(self):
        return self.__age

    def __add__(self, other):
        return Animal(self.__age + other.__age)

    def __gt__(self, other):
        return self.__age > other.__age

    def __lt__(self, other):
        return self.__age < other.__age

    def __str__(self):
        return f"Animal,年龄 {self.__age}"


c1 = Animal(5)
c2 = Animal(5)
c3 = c1 + c2

print(c1.getage())
print(c2.getage())
print(c3.getage())
print(c3 > c2)
print(c1 < c2)
print(c3)

输出:

text
5
5
10
True
False
Animal,年龄 10

c1 < c2False(5 不小于 5)。

小结

  • 运算符由特殊方法驱动;实现 __add__ 等即可自定义 + 等行为。
  • Python 3 中不要用 __idiv__/= 对应 __itruediv__
  • 比较方法应返回 boolNotImplemented;一元方法只有 self
  • 完整列表见官方「数据模型」文档;标准库 operator 模块提供与运算符对应的函数。

参考