日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Python中的魔法属性

發(fā)布時間:2024/9/15 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python中的魔法属性 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

魔法屬性

在Python中,所有以 __ 雙下劃線包起來的方法,都統(tǒng)稱為 Magic Method,例如類的初始化方法 __init__() ,實例對象創(chuàng)造方法 __new__()等。

魔法屬性和方法是Python內置的一些屬性和方法,有著特殊的含義。命名時前后加上兩個下劃線,在執(zhí)行系統(tǒng)特定操作時,會自動調用。


常見的魔法屬性

__doc__

表示類的描述信息

#?__doc__ class?Foo:"""?描述類信息,這是用于測試的類?"""def?func(self):pass#?ipython?測驗 In?[2]:?Foo.__doc__ Out[2]:?'?描述類信息,這是用于測試的類?'

__module__ 和 ?__class__

  • __module__ 表示當前操作的對象在那個模塊

  • __class__ 表示當前操作的對象的類是什么

#?__module__、__class__ #?oop.py class?Student(object):def?__init__(self,?name):self.name?=?name#?main.py from?oop?import?Students?=?Student() print(s.__module__)??#?輸出 oop 即:輸出模塊 print(s.__class__)???#?輸出?<class 'oop.Student'>?即:輸出類

__init__ 、__new__

__init__() 初始化方法 和 __new__(),通過類創(chuàng)建對象時,自動觸發(fā)執(zhí)行。__new__ 是用來創(chuàng)建類并返回這個類的實例,而 __init__ 只是將傳入的參數來初始化該實例。

  • __new__() 創(chuàng)建對象時調用,會返回當前對象的一個實例

  • __init__() 創(chuàng)建完對象后調用,對當前對象的一些實例初始化,無返回值

#?__init__?、?__new__ class?Student(object):def?__init__(self,?name,?age):print('__init__()?called')self.name?=?nameself.age?=?agedef?__new__(cls,?*args,?**kwargs):print('__new__()?called')print(cls,?args,?kwargs)return?super().__new__(cls)#?ipython?測驗 In?[26]:?s1?=?Student('hui',?age=21) __new__()?called <class?'__main__.Student'>?('hui',)?{'age':?21} __init__()?calledIn?[27]:?s2?=?Student('jack',?age=20) __new__()?called <class?'__main__.Student'>?('jack',)?{'age':?20} __init__()?called

__del__

當對象在內存中被釋放時,自動觸發(fā)執(zhí)行。

注:此方法一般無須定義,因為Python是一門高級語言,有 內存管理、垃圾回收機制,程序員在使用時無需關心內存的分配和釋放,因為此工作都是交給Python解釋器來執(zhí)行,所以,__del__ 的調用是由解釋器在進行垃圾回收時自動觸發(fā)執(zhí)行的。

#?__del__ class?Foo:def?__del__(self):print('__del__()?called')#?ipython?測驗 In?[29]:?f?=?Foo()In?[30]:?del?f __del__()?called

__call__

讓類的實例的行為表現的像函數一樣,你可以調用它們,將一個函數當做一個參數傳到另外一個函數中等等。這是一個非常強大的特性,其讓Python編程更加舒適甜美。對象后面加括號,觸發(fā)執(zhí)行

注:__init__ 方法的執(zhí)行是由創(chuàng)建對象觸發(fā)的,即:對象 = 類名() ;而對于 __call__ 方法的執(zhí)行是由對象后加括號觸發(fā)的,即:對象() 或者 類()()

__call__ 在那些 類的實例經常改變狀態(tài)的時候會非常有效。調用這個實例是一種改變這個對象狀態(tài)的直接和優(yōu)雅的做法。用一個實例來表達最好不過了:

#?__call__ class?Rect(object)"""調用實例對象來改變矩形的位置"""def?__init__(self,?x,?y):#?x,?y代表矩形坐標self.x,?self.y?=?x,?ydef?__call__(self,?x,?y):????????#?改變實體的位置self.x,?self.y?=?x,?y#?ipython?測驗 In?[33]:?r?=?Rect(10,?10)In?[34]:?r.x,?r.y Out[34]:?(10,?10)In?[35]:?r(0,?0)In?[36]:?r.x,?r.y Out[36]:?(0,?0)In?[37]:?r(100,?100)In?[38]:?r.x,?r.y Out[38]:?(100,?100)

__dict__

類或對象中的所有屬性

類的實例屬性屬于對象;類中的類屬性和方法等屬于類,即:

#?__dict__ class?Student(object):def?__init__(self,?name,?age):self.name?=?nameself._age?=?age@propertydef?age(self):return?self._age#?ipython?測驗 In?[47]:?#?獲取類屬性In?[48]:?Student.__dict__ Out[48]: mappingproxy({'__module__':?'__main__','__init__':?<function?__main__.Student.__init__(self,?name,?age)>,'age':?<property?at?0x210e2a005e8>,'__dict__':?<attribute?'__dict__'?of?'Student'?objects>,'__weakref__':?<attribute?'__weakref__'?of?'Student'?objects>,'__doc__':?None})In?[49]:?#?獲取實例對象的屬性In?[50]:?s?=?Student('hui',?21)In?[51]:?s.__dict__ Out[51]:?{'name':?'hui',?'_age':?21}In?[52]:?s2?=?Student('jack',?20)In?[53]:?s2.__dict__ Out[53]:?{'name':?'jack',?'_age':?20}

__str__

如果一個類中定義了__str__方法,那么在打印 對象 時,默認輸出該方法的返回值。

In?[65]:?#?__str__...:?class?Foo(object):...:?????pass...:In?[66]:?f?=?Foo()In?[67]:?print(f) <__main__.Foo?object?at?0x00000210E2715608>In?[68]:?class?Foo(object):...:...:?????def?__str__(self):...:?????????return?'<?Custom?Foo?object?str?>'...:In?[69]:?f?=?Foo()In?[70]:?print(f) <?Custom?Foo?object?str?>

__getitem__、__setitem__、__delitem__

用于索引操作,如字典。以上分別表示獲取、設置、刪除數據。

用于切片操作,如列表。


字典示例

#?__getitem__、__setitem__、__delitem__ class?MyDict(object):def?__init__(self):self.my_dict?=?dict()def?__getitem__(self,?key):print('__getitem__()?',?key)return?self.my_dict.get(key,?None)def?__setitem__(self,?key,?value):print('__setitem__()?',?key,?value)self.my_dict.update(key=value)def?__delitem__(self,?key):print('__delitem__()?',?key)del?self.my_dict[key]#?ipython?測驗???????? In?[33]:?mdict?=?MyDict()In?[34]:?print(mdict['name']) __getitem__()??name NoneIn?[35]:?#?新增In?[36]:?mdict['name']?=?'hui' __setitem__()??name?huiIn?[37]:?mdict['age']?=?21 __setitem__()??age?21In?[38]:?mdict['name'] __getitem__()??name Out[38]:?'hui'In?[39]:?mdict['age'] __getitem__()??age Out[39]:?21In?[40]:?#?更新In?[41]:?mdict['name']?=?'jack' __setitem__()??name?jackIn?[42]:?mdict['name'] __getitem__()??name Out[42]:?'jack'In?[43]:?#?刪除In?[44]:?del?mdict['age'] __delitem__()??ageIn?[45]:?print(mdict['age']) __getitem__()??age None

列表示例

#?切片操作 class?MyList(object):def?__init__(self):self.mlist?=?list()def?__getitem__(self,?index):print('__getitem__()?called')print(index)if?isinstance(index,?slice):return?self.mlist[index]def?__setitem__(self,?index,?value):print('__getitem__()?called')print(index,?value)if?isinstance(index,?slice):self.mlist[index]?=?valuedef?__delitem__(self,?index):print('__delitem__()?called')if?isinstance(index,?slice):del?self.mlist[index]#?ipython?測驗 In?[70]:?mlist?=?MyList()In?[71]:?mlist[0] __getitem__()?called 0In?[72]:?mlist[0:-1] __getitem__()?called slice(0,?-1,?None) Out[72]:?[]In?[73]:?mlist[:]?=?[1,2,3] __getitem__()?called slice(None,?None,?None)?[1,?2,?3]In?[74]:?mlist[:] __getitem__()?called slice(None,?None,?None) Out[74]:?[1,?2,?3]In?[75]:?mlist[0:2] __getitem__()?called slice(0,?2,?None) Out[75]:?[1,?2]In?[76]:?mlist[::-1] __getitem__()?called slice(None,?None,?-1) Out[76]:?[3,?2,?1]In?[77]:?mlist[0] __getitem__()?called 0In?[78]:?mlist[0:1] __getitem__()?called slice(0,?1,?None) Out[78]:?[1]In?[79]:?del?mlist[0:1] __delitem__()?calledIn?[80]:?mlist[:] __getitem__()?called slice(None,?None,?None) Out[80]:?[2,?3]

注意: 當進行 mlist[0] 操作的時候傳遞并不是一個 slice 對象,不是一個 int 類型的數字,所以不能把索引為 0 的值取出來,改成 mlist[0, 1] 或者在 __getitem__() 的方法中新增數字判斷,大家可以嘗試一下。


__enter__、__exit__

with 聲明是從 Python2.5 開始引進的關鍵詞。你應該遇過這樣子的代碼:

with?open('foo.txt')?as?bar:#?do?something?with?barpass

在 with 聲明的代碼段中,我們可以做一些對象的開始操作和退出操作,還能對異常進行處理。這需要實現兩個魔術方法: __enter__ 和 __exit__。

__enter__(self):

定義了當使用 with 語句的時候,會話管理器在塊被初始創(chuàng)建時要產生的行為。請注意,__enter__ 的返回值與 with 語句的目標或者 as 后的名字綁定。

__exit__(self,?exception_type,?exception_value,?traceback):

定義了當一個代碼塊被執(zhí)行或者終止后,會話管理器應該做什么。它可以被用來處理異常、執(zhí)行清理工作或做一些代碼塊執(zhí)行完畢之后的日常工作。如果代碼塊執(zhí)行成功,exception_type,exception_value,和traceback 將會為 None 。否則,你可以選擇處理這個異常或者是直接交給用戶處理。如果你想處理這個異常的話,請確保__exit__ 在所有語句結束之后返回 True。如果你想讓異常被會話管理器處理的話,那么就讓其產生該異常。


__copy__、__deepcopy__

有時候,尤其是當你在處理可變對象時,你可能想要復制一個對象,然后對其做出一些改變而不希望影響原來的對象。這就是Python的copy所發(fā)揮作用的地方。

__copy__(self):

定義了當對你的類的實例調用 copy.copy() 時所產生的行為。copy.copy() 返回了你的對象的一個淺拷貝——這意味著,當實例本身是一個新實例時,它的所有數據都被引用了——例如,當一個對象本身被復制了,它的數據仍然是被引用的(因此,對于淺拷貝中數據的更改仍然可能導致數據在原始對象的中的改變)。

__deepcopy__(self,?memodict={}):

定義了當對你的類的實例調用 copy.deepcopy()時所產生的行為。copy.deepcopy() 返回了你的對象的一個深拷貝——對象和其數據都被拷貝了。memodict 是對之前被拷貝的對象的一個緩存——這優(yōu)化了拷貝過程并且阻止了對遞歸數據結構拷貝時的無限遞歸。當你想要進行對一個單獨的屬性進行深拷貝時,調用copy.deepcopy(),并以 memodict 為第一個參數。


這些魔術方法的用例看起來很小,并且確實非常實用. 它們反應了關于面向對象程序上一些重要的東西在Python 上,并且總的來說 Python 總是一個簡單的方法去找某些事情,即使是沒有必要的。這些魔法方法可能看起來不是很有用,但是一旦你需要它們,你會感到慶幸它們的存在。


其他魔法方法

由于魔法屬性、方法太多了在這就不一一描述和展示了,其他的就以表格形式呈現吧。

用于比較的魔術方法

方法作用
__cmp__(self, other)比較方法里面最基本的的魔法方法
__eq__(self, other)定義相等符號的行為,==
__ne__(self,other)定義不等符號的行為,!=
__lt__(self,other)定義小于符號的行為,<
__gt__(self,other)定義大于符號的行為,>
__le__(self,other)定義小于等于符號的行為,<=
__ge__(self,other)定義大于等于符號的行為,>=


數值計算的魔術方法

單目運算符和函數

方法作用
__pos__(self)實現一個取正數的操作
__neg__(self)實現一個取負數的操作
__abs__(self)實現一個內建的 abs() 函數的行為
__invert__(self)實現一個取反操作符(~操作符)的行為
__round__(self, n)實現一個內建的 round() 函數的行為
__floor__(self)實現 math.floor() 的函數行為
__ceil__(self)實現 math.ceil() 的函數行為
__trunc__(self)實現 math.trunc() 的函數行為


雙目運算符或函數

方法作用
__add__(self, other)實現一個加法
__sub__(self, other)實現一個減法
__mul__(self, other)實現一個乘法
__floordiv__(self, other)實現一個 // 操作符產生的整除操作
__div__(self, other)實現一個 / 操作符代表的除法操作
__truediv__(self, other)實現真實除法
__mod__(self, other)實現一個 % 操作符代表的取模操作
__divmod__(self, other)實現一個內建函數 divmod()
__pow__(self, other)實現一個指數操作( ****** 操作符)的行為
__lshift__(self, other)實現一個位左移操作**(<<)**的功能
__rshift__(self, other)實現一個位右移操作**(>>)**的功能
__and__(self, other)實現一個按位進行與操作**(&)**的行為
__or__(self, other)實現一個按位進行或操作的行為
__xor__(self, other)異或運算符相當于 ^


增量運算

方法作用
__iadd__(self, other)加法賦值
__isub__(self, other)減法賦值
__imul__(self, other)乘法賦值
__ifloordiv__(self, other)整除賦值,地板除,相當于 //= 運算符
__idiv__(self, other)除法賦值,相當于 /= 運算符
__itruediv__(self, other)真除賦值
__imod_(self, other)模賦值,相當于 %= 運算符
__ipow__(self, other)乘方賦值,相當于 ?**= ?運算符
__ilshift__(self, other)左移賦值,相當于 <<= 運算符
__irshift__(self, other)左移賦值,相當于 >>= 運算符
__iand__(self, other)與賦值,相當于 &= 運算符
__ior__(self, other)或賦值
__ixor__(self, other)異或運算符,相當于 ^= 運算符


類型轉換

方法作用
__int__(self)轉換成整型
__long__(self)轉換成長整型
__float__(self)轉換成浮點型
__complex__(self)轉換成 復數型
__oct__(self)轉換成八進制
__hex__(self)轉換成十六進制
__index__(self)如果你定義了一個可能被用來做切片操作的數值型,你就應該定義__index__
__trunc__(self)當 math.trunc(self) ?使用時被調用 __trunc__ 返回自身類型的整型截取
__coerce__(self, other)執(zhí)行混合類型的運算

大自然用數百億年創(chuàng)造出我們現實世界,而程序員用幾百年創(chuàng)造出一個完全不同的虛擬世界。我們用鍵盤敲出一磚一瓦,用大腦構建一切。人們把1000視為權威,我們反其道行之,捍衛(wèi)1024的地位。我們不是鍵盤俠,我們只是平凡世界中不凡的締造者 。

推薦閱讀

誤執(zhí)行了rm -fr /*之后,除了跑路還能怎么辦?!

程序員必備58個網站匯總

大幅提高生產力:你需要了解的十大Jupyter Lab插件

總結

以上是生活随笔為你收集整理的Python中的魔法属性的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。