1 映射類關系

Python 的 collections.abc 模塊內擁有 Mapping 和 MutableMapping 這兩個抽象基類,它們為 dict 和其他類似的類型提供了接口定義。
mutable /ˈmjuːtəbl/ adj. Capable of or subject to change or alteration.
它們之間的類關系如下圖所示:

箭頭從子類指向父類,抽象類和抽象方法的名稱以斜體顯示。
首先是 Container、Iterable 與 Sized 三大接口,接着 Mapping 接口在繼承了前面三大接口的基礎上,又定義了一些自有接口。
這些接口定義了構建一個映射類型所需要的接口與方法。
2 判定映射類型
可以通過 isinstance() 方法來判定某個對象是不是廣義上的映射類型:
import collections import logging logging.basicConfig(level=logging.DEBUG, format='%(levelname)s - %(message)s') my_dict = {} result = isinstance(my_dict, collections.abc.Mapping) logging.info('result -> %s', result) 復制代碼
運行結果:
INFO - result -> True 復制代碼
3 可散列的數據類型
Python 標准庫里的所有映射類型都是利用 dict 來實現的,它們的鍵都必須是可散列的數據類型。
可散列的數據類型指的是:在這種數據類型對象的生命周期中,它的散列值是不變的。它會實現 __hash__() 方法與__qe__() 方法,后一種方法是用來與其他鍵做比較。如果兩個對象的散列值相等,那么就可以判定這兩個對象相等。
原子不可變的數據類型(如:str、bytes 和數值類型)都是可散列數據類型。frozenset 中只能容納可散列類型,因此也是可散列數據類型。
frozenset() 會返回一個凍結的集合,凍結后集合不能再添加或刪除元素。
而元組比較特殊,只有當一個元組中所包含的元素都是可散列類型時,它才是可散列的。Luciano Ramalho 舉了一個示例來說明這一點。
tt = (1, 2, (30, 40)) logging.info('hash(tt) -> %s', hash(tt)) tf = (1, 2, frozenset([30, 40])) logging.info('hash(tf) -> %s', hash(tf)) tl = (1, 2, [30, 40]) logging.info('hash(tl) -> %s', hash(tl)) 復制代碼
運行結果:
INFO - result -> True INFO - hash(tt) -> 8027212646858338501 INFO - hash(tf) -> 985328935373711578 TypeError: unhashable type: 'list' 復制代碼
示例中可以看到:元組內包含了一個非散列的列表,就會拋出 TypeError 異常。
一般情況下,用戶自定義類型的對象都是可散列的,散列值就是這些對象 id() 函數的返回值,因此這些對象在比較的時候都是不相等的。
本文章素材來源於網絡,如有侵權請聯系刪除。