常见的运算符重载方法
在类中,对内置对象(例如,整数和列表)所能做的事,几乎都有相应的特殊名称的重载方法。下表列出其中一些最常用的重载方法。参见http://blog.csdn.net/gavin_john/article/details/50717695
方法 | 重载 | 调用 |
---|---|---|
__init__ | 构造函数 对象建立: | X = Class(args) |
__del_ _ | 析构函数 | X对象收回 |
__add__ | 运算符+ | 如果没有_iadd_ ,X+Y,X+=Y |
__or__ | 运算符| (位OR ) | 如果没有_ior_ ,X|Y, X|=Y |
__repr__ ,__str__ | 打印、转换 | print(X) 、repr(X),str(X) |
__call__ | 函数调用 | X(*args,**kargs) |
__getattr__ | 点号运算 | X.undefined |
__setattr__ | 属性赋值语句 | X.any = value |
__delattr__ | 属性删除 | del X.any |
__getattribute__ | 属性获取 | X.any |
__getitem__ | 索引运算 | X[key],X[i:j] ,没__iter__ 时的for 循环和其他迭代器 |
__setitem__ | 索引赋值语句 | X[key] = value,X[i:j] = sequence |
__delitem__ | 索引和分片删除 | del X[key] ,del X[i:j] |
__len__ | 长度 | len(X) ,如果没有__bool__ ,真值测试 |
__bool__ | 布尔测试 | bool(X) ,真测试 |
__lt__ ,__gt__ , | 特定的比较 | X < Y,X > Y |
__le__ ,__ge__ , | X<=Y,X >= Y | |
__eq__ ,__ne__ | X == Y,X != Y | |
__radd__ | 右侧加法 | Other+X |
__iadd__ | 实地(增强的)加法 | X += Y (or else __add__) |
iter,next | 迭代环境 | I = iter(X),next(I) |
__contains__ | 成员关系测试 | item in X (任何可迭代的) |
__index__ | 整数值 | hex(X),bin(X),oct(X),O[X],O[X:] |
__enter__,__exit__ | 环境管理器 | with obj as var: |
__get__,__set__ | 描述符属性 | X.attr,X.attr = value,del X.attr |
__new__ | 创建 | 在__init__ 之前创建对象 |
对于二元运算符, 有一个invoke的顺序表, 以__eq__
为例 参见http://stackoverflow.com/questions/3588776/how-is-eq-handled-in-python-and-in-what-order
总结起来就是
左结合优先, 然后右结合, 然后其他
对于修改自己的二元操作, 比如 &=
,先__iand__
后__and__
即在找不到__ixx__
的情况下调用 __xx__
综合起来, 在尝试完了左边的运算符后, 才能尝试右边的运算符
实例如下
In [0]: class A:
...: def __init__(self):
...: self.a =1
...: def __add__(self, b):
...: print('A add')
...:
In [1]: class B:
...: def __init__(self):
...: self.a =1
...: def __iadd__(self, a):
...: print('B iadd')
...:
In [2]: a = A()
In [3]: b =B()
In [4]: a += b
A add
重载二元自操作运算符:
例如
__iand__ &=
__ior__ |=
__ixor__ ^=
__isub__ -=
#etc.
需要
1. self = 新实例
2. return self
例如:
Class OrderedSetAdapter():
# ...
def __ior__(self, other):
self = OrderedSetAdapter(self.__or__(other))
return self
更新操作
只有二元自操作运算符 __ixx__ 才能赋值self 实例 (self = xxxx)
其余方法更新实例, 只能用方法 clear + update, 创建新实例并直接赋值给self, 会在此方法结束后
失效!!
举个栗子
class OrderedSet:
# ...
def intersection_update(self, *others):
res = self.intersection(*others)
self.clear()
self.update(res)
def __iand__(self, other):
self = self.__and__(other)
return self