python零碎知識(8):UserDict 類

來源:互聯網
上載者:User

一、UserDict概述
UserDict 模組中的 UserDict 類是在python中經常使用的類,儲存在Python 安裝目錄的 lib 目錄下UserDict.py。其高仿字典(Dictionary)開啟之後可見如下:

 1 ""A more or less complete user-defined wrapper around dictionary objects.""" 2  3 class UserDict:                    [1] 4     def __init__(self, dict=None, **kwargs):   [2] 5         self.data = {}                [3] 6         if dict is not None:             [4] 7             self.update(dict)            [5] 8         if len(kwargs): 9             self.update(kwargs)10     def __repr__(self): return repr(self.data)11     def __cmp__(self, dict):12         if isinstance(dict, UserDict):13             return cmp(self.data, dict.data)14         else:15             return cmp(self.data, dict)16     def __len__(self): return len(self.data)

..................省略

 注意:
[1]. UserDict 是一個基類,不是從任何其他類繼承而來
[2].通過在 dict 參數中傳入一個字典來定義初始值
[3].Python 支援資料屬性,如上的 data (在C#、C++叫資料成員,java中叫執行個體變數)。它是由某個特定的類執行個體所擁有的資料,在本例中,每個 UserDict 執行個體將擁有一個 data 資料屬性。
  引用:(1).要從類外的代碼引用這個屬性,需要用執行個體的名字限定它,instance.data,限定的方法與你用模組的名字來限定函數一樣
     (2).要在類的內部引用一個資料屬性,我們使用 self 作為限定符

習慣上,所有的資料屬性都在 __init__ 方法中初始化為有意義的值。然而,這並不是必須的,因為資料屬性,象局部變數一樣,當你首次賦給它值的時候突然產生。
[4].if ....is...文法
[5].update 方法是一個字典複製器:它把一個字典中的鍵和值全部拷貝到另一個字典。 這個操作 並不 事先清空目標字典,如果一些鍵在目標字典中已經存在,則它們將被覆蓋,那些鍵名在目標字典中不存在的則不改變。應該把 update 看作是合并函數,而不是複製函數。

二、UserDict 常規方法

 1 def clear(self):                        #[1] 2     self.data.clear()                   #[2] 3 def copy(self):                         #[3] 4     if self.__class__ is UserDict:     #[4] 5         return UserDict(self.data) 6     import copy 7     return copy.copy(self)             #[5] 8 def keys(self): 9     self.data.keys()10 def items(self):11     self.data.items()12 def values(self):13     self.data.values()

注意:封裝類的基本技術:
將一個真正的字典 (data) 作為資料屬性儲存起來,定義所有真正字典所擁有的方法,並且將每個類方法重新導向到真正字典上的相應方法。(如上的clear,對應dictionary中的clear()方法)

 1  從 dictionary 中刪除元素 2 >>> d 3 {'server': 'mpilgrim', 'uid': 'sa', 'database': 'master',42: 'douglas', 'retrycount': 3} 4 >>> del d[42]  5 >>> d 6 {'server': 'mpilgrim', 'uid': 'sa', 'database': 'master', 'retrycount': 3} 7 >>> d.clear()  8 >>> d 9 10    del 允許您使用 key 從一個 dictionary 中刪除獨立的元素。 11   clear 從一個 dictionary 中清除所有元素。注意空的大括弧集合表示一個沒有元素的 dictionary。 

 

[1].clear 是一個普通的類方法,可以在任何時候被任何人公開調用。注意,clear 象所有的類方法一樣(常規的或專用的),使用 self 作為它的第一個參數。(記住,當你調用方法時,不用包括 self;這件事是 Python 替你做的。)

[2].真正字典的 copy 方法會返回一個新的字典,它是原始字典的原樣的複製(所有的鍵-值對都相同)。但是 UserDict 不能簡單地重新導向到 self.data.copy,因為那個方法返回一個真正的字典,而我們想要的是返回同一個類的一個新的執行個體,就象是 self。

[3].我們使用 __class__ 屬性來查看是否 self 是一個 UserDict,如果是,太好了,因為我們知道如何拷貝一個 UserDict:只要建立一個新的 UserDict ,並傳給它真正的字典,這個字典已經存放在 self.data 中了。 然後你立即返回這個新的 UserDict,你甚至於不需要再下面一行中使用 import copy。

[4].如果 self.__class__ 不是 UserDict,那麼 self 一定是 UserDict 的某個子類(如可能為 FileInfo),生活總是存在意外。 UserDict 不知道如何產生它的子類的一個原樣的拷貝,例如,有可能在子類中定義了其它的資料屬性,所以我們只能完全複製它們,確定拷貝了它們的全部內容。幸運的是,Python 帶了一個模組可以正確地完成這件事,它叫做 copy。能夠拷貝任何 Python 對象.

[5].其餘的方法是直截了當的重新導向到 self.data 的內建函數上。

三、 直接繼承自內建資料類型 dict

注意:dict是內建的資料類型,如同內建函數一般,可以在任何地方使用。在python中,可以直接繼承自內建資料類型dict,如下:
1.繼承自UserDict.UserDict

1 #繼承自 UserDict.UserDict 2 #import UserDict 這個錯誤,一定要匯入UserDict模組的UserDict類3 from UserDict import UserDict4 class FileInfo(UserDict):5     "store file metadata"6     def __init__(self, filename=None):7         UserDict.__init__(self)        8         self["name"] = filename  

2.直接繼承自內建資料類型 dict

1 #直接繼承自內建資料類型 dict2 class demo(dict):3     def __init__(self,test=None):4         self["name"]=test

我們發現第二種精簡了許多。它們之間的區別如下3點:

(1)不需要匯入 UserDict 模組,因為 dict 是已經可以使用的內建資料類型
(2)繼承方式不同,一個是繼承自 UserDict.UserDict ,另一個直接繼承自 dict
(3)UserDict 內部的工作方式要求你手工地調用它的 __init__ 方法去正確初始化它的內部資料結構。 dict 並不這樣工作,它不是一個封裝所以不需要明確的初始化。

四、python類的深入[1]

1.關於重載
在各程式設計語言中大致分為兩種重載方式:
  (1).通過參數列表的重載,一個類可以有同名的多個方法,但這些方法它們參數個數不同,或參數的類型不同,如java
  (2).支援通過參數名的重載,一個類可以有同名的多個方法,這些方法有相同類型,相同個數的參數,但參數名不同如(PL/SQL)

不過注意:Python 兩種都不支援!
總之是沒有任何形式的函數重載。一個 __init__ 方法就是一個 __init__ 方法,不管它有什麼樣的參數。每個類只能有一個 __init__ 方法,並且如果一個子類擁有一個 __init__ 方法,它總是覆蓋父類的 __init__ 方法,甚至子類可以用不同的參數列表來定義它。子類可以覆蓋父類中的方法。

2.關於資料屬性
應該總是在 __init__ 方法中給一個執行個體的所有資料屬性賦予一個初始值。這樣做將會節省你在後面調試的時間,不必為捕捉因使用未初始化(也就是不存在)的屬性而導致的 AttributeError 異常費時費力。

在 Java 中,靜態變數(在 Python 中叫類屬性)和執行個體變數(在 Python 中叫資料屬性)兩者是緊跟在類定義之後定義的(一個有 static 關鍵字,一個沒有)。在 Python 中,只有類屬性可以定義在這裡,資料屬性定義在 __init__ 方法中。

參考 Dive Into Python

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.