1. 程式人生 > >Python中的魔術方法詳解2

Python中的魔術方法詳解2

介紹

  在Python中,所有以“__”雙下劃線包起來的方法,都統稱為“Magic Method”,中文稱『魔術方法』,例如類的初始化方法 __init__ ,Python中所有的魔術方法均在官方文件中有相應描述,但是對於官方的描述比較混亂而且組織比較鬆散。很難找到有一個例子。

構造和初始化

  每個Pythoner都知道一個最基本的魔術方法, __init__ 。通過此方法我們可以定義一個物件的初始操作。然而,當呼叫 x = SomeClass() 的時候, __init__ 並不是第一個被呼叫的方法。實際上,還有一個叫做__new__ 的方法,兩個共同構成了“建構函式”。

  __new__是用來建立類並返回這個類的例項, 而__init__只是將傳入的引數來初始化該例項。

  在物件生命週期呼叫結束時,__del__ 方法會被呼叫,可以將__del__理解為“構析函式”。下面通過程式碼的看一看這三個方法:

123456789from os.path import join class FileObject: '''給檔案物件進行包裝從而確認在刪除時檔案流關閉'''def __init__(self, filepath='~', filename='sample.txt'): #讀寫模式開啟一個檔案 self.file = open(join(filepath, filename), 'r+') def __del__(self): self.file.close()
del self.file

控制屬性訪問

  許多從其他語言轉到Python的人會抱怨它缺乏類的真正封裝。(沒有辦法定義私有變數,然後定義公共的getter和setter)。Python其實可以通過魔術方法來完成封裝。我們來看一下:

1__getattr__(self, name):

  定義當用戶試圖獲取一個不存在的屬性時的行為。這適用於對普通拼寫錯誤的獲取和重定向,對獲取一些不建議的屬性時候給出警告(如果你願意你也可以計算並且給出一個值)或者處理一個 AttributeError 。只有當呼叫不存在的屬性的時候會被返回。

1__setattr__(self, name, value):

  與__getattr__(self, name)不同,__setattr__ 是一個封裝的解決方案。無論屬性是否存在,它都允許你定義對對屬性的賦值行為,以為這你可以對屬性的值進行個性定製。實現__setattr__時要避免"無限遞迴"的錯誤。

1__delattr__:

  與 __setattr__ 相同,但是功能是刪除一個屬性而不是設定他們。實現時也要防止無限遞迴現象發生。

1__getattribute__(self, name):

  __getattribute__定義了你的屬性被訪問時的行為,相比較,__getattr__只有該屬性不存在時才會起作用。因此,在支援__getattribute__的Python版本,呼叫__getattr__前必定會呼叫 __getattribute__。__getattribute__同樣要避免"無限遞迴"的錯誤。需要提醒的是,最好不要嘗試去實現__getattribute__,因為很少見到這種做法,而且很容易出bug。

  在進行屬性訪問控制定義的時候很可能會很容易引起“無限遞迴”。如下面程式碼:

123456789#  錯誤用法 def __setattr__(self, name, value): self.name = value # 每當屬性被賦值的時候(如self.name = value), ``__setattr__()`` 會被呼叫,這樣就造成了遞迴呼叫。 # 這意味這會呼叫 ``self.__setattr__('name', value)`` ,每次方法會呼叫自己。這樣會造成程式崩潰。 #  正確用法 def __setattr__(self, name, value): self.__dict__[name] = value  # 給類中的屬性名分配值 # 定製特有屬性

Python的魔術方法很強大,但是用時卻需要慎之又慎,瞭解正確的使用方法非常重要。

建立自定義容器

  有很多方法可以讓你的Python類行為向內建容器型別一樣,比如我們常用的list、dict、tuple、string等等。Python的容器型別分為可變型別(如list、dict)和不可變型別(如string、tuple),可變容器和不可變容器的區別在於,不可變容器一旦賦值後,不可對其中的某個元素進行修改。

  在講建立自定義容器之前,應該先了解下協議。這裡的協議跟其他語言中所謂的"介面"概念很像,它給你很多你必須定義的方法。然而在Python中的協議是很不正式的,不需要明確宣告實現。事實上,他們更像一種指南。

自定義容器的magic method

  下面細緻瞭解下定義容器可能用到的魔術方法。首先,實現不可變容器的話,你只能定義 __len__ 和 __getitem__ (下面會講更多)。可變容器協議則需要所有不可變容器的所有,另外還需要 __setitem__ 和 __delitem__ 。如果你希望你的物件是可迭代的話,你需要定義 __iter__ 會返回一個迭代器。迭代器必須遵循迭代器協議,需要有 __iter__(返回它本身) 和 next。

1__len__(self):

  返回容器的長度。對於可變和不可變容器的協議,這都是其中的一部分。

1__getitem__(self, key):

  定義當某一項被訪問時,使用self[key]所產生的行為。這也是不可變容器和可變容器協議的一部分。如果鍵的型別錯誤將產生TypeError;如果key沒有合適的值則產生KeyError。

1

相關推薦

Python魔術方法2

介紹  在Python中,所有以“__”雙下劃線包起來的方法,都統稱為“Magic Method”,中文稱『魔術方法』,例如類的初始化方法 __init__ ,Python中所有的魔術方法均在官方文件中有相應描述,但是對於官方的描述比較混亂而且組織比較鬆散。很難找到有一個例子。構造和初始化  每個Python

pythonlist方法說明

序號 分類 關鍵字/函式/方法 描述 1 新增 list.insert(索引,資料) 在指定位置插入資料     list.append(資料)

pythonnew方法

new_ 方法是什麼? __new__方法其實就是建立物件的方法 new()方法是在類準備將自身例項化時呼叫。 一個類可以有多個位置引數和多個命名引數,而在例項化開始之後,在呼叫 init()方法之前,Python首先呼叫new()方法: def new(cls, *args, **kw

Python魔術方法

介紹   在Python中,所有以“__”雙下劃線包起來的方法,都統稱為“Magic Method”,中文稱『魔術方法』,例如類的初始化方法 __init__ ,Python中所有的魔術方法均在官方文件中有相應描述,但是對於官方的描述比較混亂而且組織比較鬆散。很難找到有一個例子。 構造和初始化   每個Pyt

JavaScriptgetBoundingClientRect()方法

script otto java chrome 頁面 支持 urn client fire getBoundingClientRect() 這個方法返回一個矩形對象,包含四個屬性:left、top、right和bottom。分別表示元素各邊與頁面上邊和左邊的距離。

Pythonenumerate用法

num readline 文件的 簡單 += () 用法 字符 計數 enumerate()是python的內置函數、適用於python2.x和python3.xenumerate在字典上是枚舉、列舉的意思enumerate參數為可遍歷/可叠代的對象(如列表、字符串)enu

Python List insert()方法

返回 -- 定位 abs pre insert 詳解 頭部 表示 1.功能insert()函數用於將指定對象插入列表的指定位置。 2.語法list.insert(index, obj) 3.參數index: 對象obj需要插入的索引位置。obj: 插入列表中的對象。

boost庫sleep方法

seconds boost庫 color sys 在線 TP 方法 轉載 details 博客轉載自:https://blog.csdn.net/huang_xw/article/details/8453506 boost庫中sleep有兩個方法: 1. 這個方法只能在線程

python魔術方法簡述

圖片 water pro 程序 基類 get ffffff http cbc 魔術方法:***實例化:new :實例化一個對象 方法很少使用,一般使用return super().))new(cls)基類ibject方法來創建實例並返回。 hash:返回一個整數,如

python閉包

ner copy bsp div 執行 gpo 註意 outer 在一起 閉包這個概念好難理解,身邊朋友們好多都稀裏糊塗的,稀裏糊塗的林老冷希望寫下這篇文章能夠對稀裏糊塗的夥伴們有一些幫助~ 請大家跟我理解一下,如果在一個函數的內部定義了另一個函數,外部的我們叫

python~random常用方法

random常用方法詳解 random:生成0到1之間的隨機浮點數 >>> import random >>> random.random() 0.7752409555996718 uniform(a,

JS陣列方法

JS中陣列的方法有很多,但是自己一直沒有抽時間進行整理分類,故單獨寫一篇博文,對目前我所掌握的JS中陣列相關的方法進行整理,夯實一下自己的基礎。 我將陣列相關的方法分為兩類 1.方法會改變原陣列 相應的方法有:shift、unshift、pop、push、rev

AndroidJNI使用(2)---Android StudioNDK環境配置

Android Studio中的NDK環境配置 1、下載NKD 在Android Studio中選擇File----Settings----Appearance&Behavior---System Settings----Andr

Java 的Stringintern方法及測試樣例

intern public String intern() 返回字串物件的規範化表示形式。 一個初始時為空的字串池,它由類 String 私有地維護。 當呼叫 intern 方法時,如果池已經包含一個等於此 String 物件的字串(該物件由 equals(Obj

python:__getitem__方法

__getitem__(self,key): 這個方法返回與指定鍵想關聯的值。對序列來說,鍵應該是0~n-1的整數,其中n為序列的長度。對對映來說,鍵可以是任何型別。 class Tag: def __init__(self,id): self.id=id

聊聊Python的GIL python的GIL

對於廣大寫Python的人來說,GIL(Global Interpreter Lock, 全域性直譯器鎖)肯定不陌生,但未必清楚GIL的歷史和全貌是怎樣的,今天我們就來梳理一下GIL。 1. 什麼是GIL GIL的全稱是 Global Interpreter Lock,全域性直譯器鎖。之所以叫這

Python內建方法

  1. 簡介   本指南主題是 魔法方法 。   所以,為了修復我感知的Python文件的缺陷,我開始提供更為通俗的,有示例支援的Python魔法方法指南。我一開始 寫了一些博文,現在我把這些博文總起來成為一篇指南。   希望你喜歡這篇指南,一篇友好,通俗易懂的Python魔法方法指南!   2.

pythonsocket模組

socket模組簡介 網路上的兩個程式通過一個雙向的通訊連線實現資料的交換,這個連線的一端稱為一個socket。socket通常被叫做“套接字”,用於描述IP地址和埠,是一個通訊鏈的控制代碼,可以用來實現不同虛擬機器或不同計算機之間的通訊。在Internet上的主機一般運行了多個服務

Python的generator

注:本文在原文基礎上做了一點點修改,僅僅作為個人理解與記憶,建議直接檢視原文。 generator使用場景:   1  當我們需要一個公用的,按需生成的資料   2  某個事情執行一部分,另一部分在某個事件發生後再執行下一部分,實現非同步。 注意事項:  

pythonpsutil模組

         在Python中獲取系統資訊的另一個好辦法是使用psutil這個第三方模組。顧名思義,psutil = process and system utilities,它不僅可以通過一兩行程式碼實現系統監控,還可以跨平臺使用,支援Linu