Python 運算符重載

常見的運算符重載方法

在類中,對內置對象(例如,整數和列表)所能做的事,幾乎都有相應的特殊名稱的重載方法。下表列出其中一些最常用的重載方法。參見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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章