1. 程式人生 > >Python的運算子過載 __iter__()和 __next__()

Python的運算子過載 __iter__()和 __next__()

   Python語言提供了運算子過載功能,增強了語言的靈活性,這一點與C++有點類似又有些不同。鑑於它的特殊性,今天就來討論一下Python運算子過載。

      Python語言本身提供了很多魔法方法,它的運算子過載就是通過重寫這些Python內建魔法方法實現的。這些魔法方法都是以雙下劃線開頭和結尾的,類似於__X__的形式,python通過這種特殊的命名方式來攔截操作符,以實現過載。當Python的內建操作運用於類物件時,Python會去搜索並呼叫物件中指定的方法完成操作。

       類可以過載加減運算、列印、函式呼叫、索引等內建運算,運算子過載使我們的物件的行為與內建物件的一樣。Python在呼叫操作符時會自動呼叫這樣的方法,例如,如果類實現了__add__方法,當類的物件出現在+運算子中時會呼叫這個方法。

常見運算子過載方法

方法名

過載說明

運算子呼叫方式

__init__

建構函式

物件建立: X = Class(args)

__del__

解構函式

X物件收回

__add__/__sub__

加減運算

 X+Y, X+=Y/X-Y, X-=Y

__or__

運算子|

X|Y, X|=Y

_repr__/__str__

列印/轉換

print(X)、repr(X)/str(X)

__call__

函式呼叫

X(*args, **kwargs)

__getattr__

屬性引用

X.undefined

__setattr__

屬性賦值

X.any=value

__delattr__

屬性刪除

del X.any

__getattribute__

屬性獲取

X.any

__getitem__

索引運算

X[key],X[i:j]

__setitem__

索引賦值

X[key],X[i:j]=sequence

__delitem__

索引和分片刪除

del X[key],del X[i:j]

__len__

長度

len(X)

__bool__

布林測試

bool(X)

__lt__, __gt__, 

__le__, __ge__, 

__eq__, __ne__

特定的比較

依次為X<Y,X>Y,X<=Y,X>=Y, 

X==Y,X!=Y 

註釋:(lt: less than, gt: greater than, 

  le: less equal, ge: greater equal, 

  eq: equal, ne: not equal 

__radd__

右側加法

other+X

__iadd__

實地(增強的)加法

X+=Y(or else __add__)

__iter__, __next__

迭代

I=iter(X), next()

__contains__

成員關係測試

item in X(X為任何可迭代物件)

__index__

整數值

hex(X), bin(X),  oct(X)

__enter__, __exit__

環境管理器

with obj as var:

__get__, __set__, 

__delete__

描述符屬性

X.attr, X.attr=value, del X.attr

__new__

建立

在__init__之前建立物件


       下面對常用的運算子方法的使用進行一下介紹。

建構函式和解構函式:__init__和__del__

       它們的主要作用是進行物件的建立和回收,當例項建立時,就會呼叫__init__構造方法。當例項物件被收回時,解構函式__del__會自動執行。

  1. >>> class Human():  
  2. ...     def __init__(self, n):  
  3. ...         self.name = n  
  4. ...             print("__init__ ",self.name)  
  5. ...     def __del__(self):  
  6. ...         print("__del__")  
  7. ...   
  8. >>> h = Human('Tim')  
  9. __init__  Tim  
  10. >>> h = 'a'
  11. __del__  

加減運算:__add__和__sub__

       過載這兩個方法就可以在普通的物件上新增+-運算子操作。下面的程式碼演示瞭如何使用+-運算子,如果將程式碼中的__sub__方法去掉,再呼叫減號運算子就會出錯。

  1. >>> class Computation():  
  2. ...     def __init__(self,value):  
  3. ...         self.value = value  
  4. ...     def __add__(self,other):  
  5. ...         returnself.value + other  
  6. ...     def __sub__(self,other):  
  7. ...         returnself.value - other  
  8. ...   
  9. >>> c = Computation(5)  
  10. >>> c + 5
  11. 10
  12. >>> c - 3
  13. 2

物件的字串表達形式:__repr__和__str__

       這兩個方法都是用來表示物件的字串表達形式:print()、str()方法會呼叫到__str__方法,print()、str()和repr()方法會呼叫__repr__方法。從下面的例子可以看出,當兩個方法同時定義時,Python會優先搜尋並呼叫__str__方法。

  1. >>> class Str(object):  
  2. ...     def __str__(self):  
  3. ...         return"__str__ called"
  4. ...     def __repr__(self):  
  5. ...         return"__repr__ called"
  6. ...   
  7. >>> s = Str()  
  8. >>> print(s)  
  9. __str__ called  
  10. >>> repr(s)  
  11. '__repr__ called'
  12. >>> str(s)  
  13. '__str__ called'

索引取值和賦值:__getitem__, __setitem__

       通過實現這兩個方法,可以通過諸如 X[i] 的形式對物件進行取值和賦值,還可以對物件使用切片操作。

  1. >>> class Indexer:  
  2.     data = [1,2,3,4,5,6]  
  3.     def __getitem__(self,index):  
  4.         returnself.data[index]  
  5.     def __setitem__(self,k,v):  
  6.         self.data[k] = v  
  7.         print(self.data)  
  8. >>> i = Indexer()  
  9. >>> i[0]  
  10. 1
  11. >>> i[1:4]  
  12. [234]  
  13. >>> i[0]=10
  14. [1023456]  

設定和訪問屬性:__getattr__、__setattr__

       我們可以通過過載__getattr__和__setattr__來攔截對物件成員的訪問。__getattr__在訪問物件中不存在的成員時會自動呼叫。__setattr__方法用於在初始化物件成員的時候呼叫,即在設定__dict__的item時就會呼叫__setattr__方法。具體例子如下:

  1. class A():  
  2.     def __init__(self,ax,bx):  
  3.         self.a = ax  
  4.         self.b = bx  
  5.     def f(self):  
  6.         print (self.__dict__)  
  7.     def __getattr__(self,name):  
  8.         print ("__getattr__")  
  9.     def __setattr__(self,name,value):  
  10.         print ("__setattr__")  
  11.         self.__dict__[name] = value  
  12. a = A(1,2)  
  13. a.f()  
  14. a.x  
  15. a.x = 3
  16. a.f()  

       上面程式碼的執行結果如下,從結果可以看出,訪問不存在的變數x時會呼叫__getattr__方法;當__init__被呼叫的時候,賦值運算也會呼叫__setattr__方法。

  1. __setattr__  
  2. __setattr__  
  3. {'a'1'b'2}  
  4. __getattr__  
  5. __setattr__  
  6. {'a'1'x'3'b'2}  

迭代器物件: __iter__,  __next__

       Python中的迭代,可以直接通過過載__getitem__方法來實現,看下面的例子。

  1. >>> class Indexer:  
  2. ...     data = [1,2,3,4,5,6]  
  3. ...     def __getitem__(self,index):  
  4. ...             returnself.data[index]  
  5. ...   
  6. >>> x = Indexer()  
  7. >>> for item in x:  
  8. ...     print(item)  
  9. ...   
  10. 1
  11. 2
  12. 3
  13. 4
  14. 5
  15. 6
       通過上面的方法是可以實現迭代,但並不是最好的方式。Python的迭代操作會優先嚐試呼叫__iter__方法,再嘗試__getitem__。迭代環境是通過iter去嘗試尋找__iter__方法來實現,而這種方法返回一個迭代器物件。如果這個方法已經提供,Python會重複呼叫迭代器物件的next()方法,直到發生StopIteration異常。如果沒有找到__iter__,Python才會嘗試使用__getitem__機制。下面看一下迭代器的例子。
  1. class Next(object):  
  2.     def __init__(self, data=1):  
  3.         self.data = data  
  4.     def __iter__(self):  
  5.         returnself
  6.     def __next__(self):  
  7.         print("__next__ called")  
  8. 相關推薦

    Python運算子過載 __iter__() __next__()

       Python語言提供了運算子過載功能,增強了語言的靈活性,這一點與C++有點類似又有些不同。鑑於它的特殊性,今天就來討論一下Python運算子過載。       Python語言本身提供了很多魔法方法,它的運算子過載就是通過重寫這些Python內建魔法方法實現的。

    python中的__iter__ __reversed__ __next__

    返回 兩個 def .org rar 對象 關系 pes 定義 __reversed__ 返回集合的倒敘叠代器,如果沒有實現這個方法,reversed()會去使用__getitem__和__len__來實現介紹__next__和 __iter__方法需要了解下可叠代對象(i

    python3:深刻理解__iter____next__ 迭代器的原理(用自定義迭代器方法進行講解)

    1.iter 的用法 咱都知道, list ,tuple,dict 都是可迭代物件,如果想讓他們轉化成迭代器. 我們可以這麼做,呼叫 inter()方法,它會返回一個迭代器. 例如: from collections import Iterable,Iterator a=[1,

    Python——運算子過載(2)

    繼續介紹運算子過載的知識。 ======================================================================== 屬性引用:__getattr__和__setattr__ __getattr__方法是攔截屬性點號

    Python——運算子過載(1)

    運算子過載 關鍵概念: 1.運算子過載讓類攔截常規的Python運算。 2.類可過載所有的Python表示式運算子。 3.類也可過載列印、函式呼叫、屬性點號運算等內建運算。 4.過載使類例項的行為像內建型別。 5.過載是通過特殊名稱的類方法來實現的。 運算子過載只是意味著在

    Python 運算子過載

    常見的運算子過載方法 方法 過載 呼叫 __init__ 建構函式 物件建立: X = Class(args) __del__ 解構函式 X物件收回 __add__ 運算子+ 如果沒有_i

    python運算子過載

    剛剛學習python,對於運算子過載,也不是很懂,個人理解如下: 類的專有方法(未截完): ------------------------------------------------------------------------------------------

    Python ==運算子過載

    在Python中is、==是兩個運算子,對物件進行比較,分別對ID,TYPE,Value進行比較。 "is"比較ID,TYPE,Value三維,而"=="僅比較value。 實驗發現其實is,==僅僅是比較一些簡單的基礎變數。 class Test(object):

    PythonPython運算子過載(簡版)

    __add__(self, other): + __sub__(self, other): - __mul__(self, other): * __matmul__(self, other): @ __truediv__(self, other): / __floordiv_

    python Class: 面向對象高級編程 __iter__ next()

    turn std png nag fib cto 1.2 cts resp 官網解釋:New in version 2.2.iterator.__iter__()Return the iterator object itself. This is required to a

    Python3底層函式重寫運算子過載

    底層函式重寫                   Python是支援重寫底層函式的,在列印物件時,               &n

    Python 看書的一些記錄 運算子過載

    1.類和模組有什麼關係?   (1)類是模組的一部分,是模組物件的屬性。   (2)類和模組都是名稱空間,但是類是對於語法的。模組是對於檔案的   (3)類支援多個例項,但是模組被匯入時只有一個。 2.什麼是抽象超類(抽象基類)?   抽象超類就是指類的部分行為需要由其子類提供 class

    C++類物件.四個預設成員函式(賦值運算子過載

    1.(1)類的定義   類就是具有相同資料和相同操作的一組物件的集合。 學生類定義: class student {//成員變數char* name;int age;int sex;//成員函式void speak(){cout<<name<<"年

    運算子過載友元函式

    運算子過載的意義是:將常見的運算子重載出其他的含義:比如將*重載出指標的含義,將<<與cout聯合使用重載出輸出的含義,但需要認識到的問題是:運算子的過載:本質仍然是成員函式,即你可以認為:發生運算子過載時,實際上,是呼叫了成員函式,只不過重新換了個名字,叫運算子過載。 友元函式的意義:使得我們

    (D20)Python-異常高階,運算子過載

    異常(高階) 異常相關的語句: try-except try-finally raise 觸發異常,發生錯誤通知 assert 根據條件觸發AssertionError型別的錯誤通知 with 語句 with語句 語法:

    day02pycham的安裝教程啟用碼,以及python運算子,字串等等知識點

    成員運算子 例如有一個人的名字是"周杰倫" 在python裡面的程式碼是:`name = “周杰倫” name是一個字串,這個字串是由周 傑 倫這三個字元組成的., in這兩個關鍵字可以判斷一個字串裡面包不包含這個字串 not in 程式碼是: name = "

    C++拷貝建構函式運算子過載(VC實現)

    String.h檔案: #ifndef STRING_H #define STRING_H #include <ostream> using namespace std; class String { public: String(){ m_pStr = nullptr

    C++ 複製建構函式運算子過載示例

    string1.h // // Created by lance on 10/16/18. // #ifndef CPP_PRIMER_STRING1_H #define CPP_PRIMER_STRING1_H #include <iostream> u

    c++成員運算子過載友元運算子過載的比較(以++,--運算子為例)

    1、對雙目運算子而言,成員運算子過載函式引數列表中含有一個引數,而友元運算子過載函式引數列表含有兩個引數;對單目運算子而言,成員運算子過載函式引數列表中沒有引數,而友元運算子過載函式引數列表含有一個引數。 2、雙目運算子一班可以被過載為友元運算子和成員函式運算