天天看點

《Python Cookbook(第2版)中文版》——1.3 測試一個對象是否是類字元串

本節書摘來自異步社群《python cookbook(第2版)中文版》一書中的第1章,第1.3節,作者[美]alex martelli , anna martelli ravenscrof , david ascher ,高鐵軍 譯,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

任務

有時候需要測試一個對象,尤其是當你在寫一個函數或者方法的時候,經常需要測試傳入的參數是否是一個字元串(或者更準确地說,這個對象是否具有類似于字元串的行為模式)。

解決方案

下面給出一個利用内建的isinstance和basestring來簡單快速地檢查某個對象是否是字元串或者unicode對象的方法,如下:

讨論

很多遇到這個問題的程式員第一反應是進行類型測試:

然而,這種方法非常糟糕,因為它破壞了python強大力量的源泉—平滑的、基于簽名的多态機制。很明顯unicode對象無法通過這個測試,使用者自己編寫的str的子類也不行,甚至任何一種行為表現類似于字元串的使用者自定義類型的執行個體都無法通過測試。

本節推薦的内建函數isinstance則要好很多。内建類型basestring的存在使得這個方法成為可能。basestring是str和unicode類型的共同基類,任何類字元串的使用者自定義類型都應該從基類basestring派生,這樣能保證isinstance的測試按照預期工作。本質上basestring是一個“空”的類型,就像object,是以從它派生子類并沒有什麼開銷。

不幸的是,這個似乎完美的isinstance檢查方案,對于python标準庫中的userstring子產品提供的userstring類的執行個體,完全無能為力。而userstring對象是非常明顯的類字元串對象,隻不過它不是從basestring派生的。如果想支援這種類型,可以直接檢查一個對象的行為是否真的像字元串一樣,比如:

這個isstringlike函數比方案中給出的isastring函數慢且複雜得多,但它的确适用于userstring(以及其他的類字元串的類型)的執行個體,也适用于str和unicode。

python中通常的類型檢查方法是所謂的鴨子判斷法:如果它走路像鴨子,叫聲也像鴨子,那麼對于我們的應用而言,就可以認為它是鴨子了。isstringlike函數隻不過檢查了叫聲部分,那其實還不夠。如果需要檢查anobj對象的更多的類字元串特征,可以改造try子句,讓它檢查更多細節,比如:

根據我的經驗,isstringlike函數的測試通常就已經滿足需要了。

進行類型驗證(或者任何驗證任務)的最具python特色的方法是根據自己的預期去執行任務,在此過程中檢測并處理由于不比對産生的所有錯誤和異常。這是一個著名的處理方式,叫做“獲得事後原諒總是比事先得到許可要容易得多(it's easier to ask forgiveness than permission)”,或簡稱eafp。try/except是保證eafp處理風格的關鍵工具。有時,像本節中的例子一樣,可以選擇一個簡單的判斷方法,比如拼接一個空字元串,作為對一系列屬性的集合(字元串對象提供的各種操作和方法)的一個替代性判斷。