1. 程式人生 > >python3:dict的子類_defaultdict

python3:dict的子類_defaultdict

我們是可以繼承dict 的,程式碼如下

class My_dict(dict):
    def __setitem__(self, key, value):
        super().__setitem__(key,value*value)

a=My_dict(one=2)

print(a["one"])

列印結果:
2

My_dict 子類繼承了dict ,並呼叫了父類的setitem,並針對value做了一個乘積,

從結果我們發現並沒有乘積。為了找原因也得爬原始碼查詢dict 的setitem方法如下

        def __setitem__(self, *args, **kwargs): # real signature unknown
        """ Set self[key] to value. """
        pass

這個方法沒有做任何處理,並不適用繼承dict,難道就沒有辦法嗎,
python 給你關閉一扇窗,會給你再開一個門,這個門就是
繼承Userdict 可以實現乘積,請看程式碼

from collections import  UserDict
class My_dict(UserDict):
    def __setitem__(self, key, value):
        super().__setitem__(key,value*value)

a=My_dict(one=2)

print(a["one"])

列印結果:

4

刨析原始碼檢視 這個方法

def __setitem__(self, key, item): self.data[key] = item

道理很明白了吧 ,我也不用解釋了。

下邊介紹重量級的人物就是 defautdict
因為他可以重寫一個魔法函式 missing ,我們按照順序介紹下

檢視 UserDict的getitem 方法如下:

    def __getitem__(self, key):
        if key in self.data:
            return self.data[key]
        if hasattr(self.__class__, "__missing__"):
            return self.__class__.__missing__(self, key)
       raise KeyError(key)

有兩個if 語句
1.如果key存在返回value
2.如果不存在就return missing魔法函式 。

我們檢視 defautdict 裡面的missing 魔法函式

    def __missing__(self, key): # real signature unknown; restored from __doc__
        """
        __missing__(key) # Called by __getitem__ for missing key; pseudo-code:
          if self.default_factory is None: raise KeyError((key,))
          self[key] = value = self.default_factory()
          return value
        """
        pass

從上邊的描述有個關鍵資訊 self[key] = value = self.default_factory()

如果不存在我會給個預設值

default_factory() 這個方法有property屬性,可以自己查下,我在以後的章節再介紹。

程式碼例子如下:

from collections import  UserDict,defaultdict

my_dict={"person":1}
my_dict=defaultdict(int)
value=my_dict["animal"]
print(value)
列印結果:
0

如果沒有 defaultdict 一定會報keyerror,自己可以試試。
由於defaultdict 有missing 方法,避免了報keyerror。

下邊講講基本的用處
1.型別名稱作為初始化函式引數

from collections import  UserDict,defaultdict

fruit=["apple","banana","orange"]

v=defaultdict(int)

for i in fruit:
    v[i]+=1
print(v)

列印結果:

defaultdict(<class 'int'>, {'apple': 1, 'banana': 1, 'orange': 1})

如果defaultdict(int) 初始化數值預設是0,如果是str是空, 如果是list是[],如果是dict是{}
自己可以嘗試下

2.可以呼叫函式作為初始化函式引數

from collections import  UserDict,defaultdict

def add():
    return 8+9

v=defaultdict(add)

value=v["boody"]
print(value)

列印的結果是:

17

defautdict 作為dict 子類用處很大,上邊的例子呼叫了方法作為預設值,這個在實際應用的用的最多,請大家記牢。