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__會自動執行。
- >>> class Human():
- ... def __init__(self, n):
- ... self.name = n
- ... print("__init__ ",self.name)
- ... def __del__(self):
- ... print("__del__")
- ...
- >>> h = Human('Tim')
- __init__ Tim
- >>> h = 'a'
- __del__
加減運算:__add__和__sub__
過載這兩個方法就可以在普通的物件上新增+-運算子操作。下面的程式碼演示瞭如何使用+-運算子,如果將程式碼中的__sub__方法去掉,再呼叫減號運算子就會出錯。
- >>> class Computation():
- ... def __init__(self,value):
- ... self.value = value
- ... def __add__(self,other):
- ... returnself.value + other
- ... def __sub__(self,other):
- ... returnself.value - other
- ...
- >>> c = Computation(5)
- >>> c + 5
- 10
- >>> c - 3
- 2
物件的字串表達形式:__repr__和__str__
這兩個方法都是用來表示物件的字串表達形式:print()、str()方法會呼叫到__str__方法,print()、str()和repr()方法會呼叫__repr__方法。從下面的例子可以看出,當兩個方法同時定義時,Python會優先搜尋並呼叫__str__方法。
- >>> class Str(object):
- ... def __str__(self):
- ... return"__str__ called"
- ... def __repr__(self):
- ... return"__repr__ called"
- ...
- >>> s = Str()
- >>> print(s)
- __str__ called
- >>> repr(s)
- '__repr__ called'
- >>> str(s)
- '__str__ called'
索引取值和賦值:__getitem__, __setitem__
通過實現這兩個方法,可以通過諸如 X[i] 的形式對物件進行取值和賦值,還可以對物件使用切片操作。
- >>> class Indexer:
- data = [1,2,3,4,5,6]
- def __getitem__(self,index):
- returnself.data[index]
- def __setitem__(self,k,v):
- self.data[k] = v
- print(self.data)
- >>> i = Indexer()
- >>> i[0]
- 1
- >>> i[1:4]
- [2, 3, 4]
- >>> i[0]=10
- [10, 2, 3, 4, 5, 6]
設定和訪問屬性:__getattr__、__setattr__
我們可以通過過載__getattr__和__setattr__來攔截對物件成員的訪問。__getattr__在訪問物件中不存在的成員時會自動呼叫。__setattr__方法用於在初始化物件成員的時候呼叫,即在設定__dict__的item時就會呼叫__setattr__方法。具體例子如下:
- class A():
- def __init__(self,ax,bx):
- self.a = ax
- self.b = bx
- def f(self):
- print (self.__dict__)
- def __getattr__(self,name):
- print ("__getattr__")
- def __setattr__(self,name,value):
- print ("__setattr__")
- self.__dict__[name] = value
- a = A(1,2)
- a.f()
- a.x
- a.x = 3
- a.f()
上面程式碼的執行結果如下,從結果可以看出,訪問不存在的變數x時會呼叫__getattr__方法;當__init__被呼叫的時候,賦值運算也會呼叫__setattr__方法。
- __setattr__
- __setattr__
- {'a': 1, 'b': 2}
- __getattr__
- __setattr__
- {'a': 1, 'x': 3, 'b': 2}
迭代器物件: __iter__, __next__
Python中的迭代,可以直接通過過載__getitem__方法來實現,看下面的例子。
- >>> class Indexer:
- ... data = [1,2,3,4,5,6]
- ... def __getitem__(self,index):
- ... returnself.data[index]
- ...
- >>> x = Indexer()
- >>> for item in x:
- ... print(item)
- ...
- 1
- 2
- 3
- 4
- 5
- 6
- class Next(object):
- def __init__(self, data=1):
- self.data = data
- def __iter__(self):
- returnself
- def __next__(self):
- print("__next__ called")
-
相關推薦
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):
Python:Python運算子過載(簡版)
__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
定義一個複數類Complex,過載運算子“+”,“-”,“*”,“/”,使之能用於複數的加、減、乘、除。運算子過載函式作為Complex類的成員函式。編寫程式,分別求兩個複數之和、差、積和商。
#include <iostream> #include <iomanip> using namespace std; class Complex { public: Complex(); Complex(double r
c++成員運算子過載和友元運算子過載的比較(以++,--運算子為例)
1、對雙目運算子而言,成員運算子過載函式引數列表中含有一個引數,而友元運算子過載函式引數列表含有兩個引數;對單目運算子而言,成員運算子過載函式引數列表中沒有引數,而友元運算子過載函式引數列表含有一個引數。 2、雙目運算子一班可以被過載為友元運算子和成員函式運算