Python內置UserDict類、實現子類調用父類的方法



Python內置的UserDict類提供私人定制字典,在學習的過程中對其中的一些地方產生了疑惑
基類中的__init__:

      def __init__(self, dict=None, **kwargs):
        self.data = {}
        if dict is not None:
            self.update(dict)

在基類中重寫了__update__方法,self.update(dict)實際上是self.update.data(dict)復制dict參數到字典data

    def update(self, dict=None, **kwargs):
        if dict is None:
            pass
        elif isinstance(dict, UserDict):
            self.data.update(dict.data)
        elif isinstance(dict, type({})) or not hasattr(dict, 'items'):
            self.data.update(dict)
        else:
            for k, v in dict.items():
                self[k] = v
        if len(kwargs):
            self.data.update(kwargs)

現在我們看一個例子:

class based:
    def __init__(self, dict = None):
        self.data = {}
        if dict is not None:
            self.data.update(dict)
    def __setitem__(self, key, item):self.data[key] = item


class child(based):
    def __init__(self, names = None):
        based.__init__(self)
        self["name"] = names

a = based({"a":"ba"})
b = child("ah")
print a.data
print b.data

在學習的過程中,對self["name"] = names 不太理解是如何實現的
仔細看chid類(繼承自based)的__init__方法,調用父類的__init__初始化了一個空的數據屬性字典data.
self["name"] = names 其實等於 self.__setitem__(self , "name", "names")
很簡單,__setitem__是python專用類方法,由python自動調用

實現子類調用父類的方法


1.調用未綁定的超類構造方法

像上面的例子演示的一樣,在子類的構造函數中使用 based.__init__(self)
這種方法叫做調用父類的未綁定的構造方法。在調用一個實例的方法時,該方法的self參數會被自動綁定到實例上(稱為綁定方法)
但如果直接調用類的方法(比如based.__init),那么就沒有實例會被綁定。這樣就可以自由的提供需要的self參數,這種方法稱為未綁定unbound方法。通過將當前的實例作為self參數提供給未綁定方法,B類就能使用其父類構造方法,從而namea變量被設置。

2.使用super函數

#父類需要繼承object對象
class A(object):
    def __init__(self):
        self.namea="aaa"
    def funca(self):
        print "function a : %s"%self.namea
class B(A):
    def __init__(self):
        #這一行解決問題
        super(B,self).__init__()
        self.nameb="bbb"
    def funcb(self):
        print "function b : %s"%self.nameb
b=B()
print b.nameb
b.funcb()
b.funca()

如上有注釋的為新增的代碼,其中第一句讓類A繼承自object類,這樣才能使用super函數,因為這是python的“新式類”支持的特性。當前的類和對象可以作為super函數的參數使用,調用函數返回的對象的任何方法都是調用超類的方法,而不是當前類的方法。
super函數會返回一個super對象,這個對象負責進行方法解析,解析過程其會自動查找所有的父類以及父類的父類。
方法一更直觀,方法二可以一次初始化所有超類
super函數比在超累中直接調用未綁定方法更直觀,但是其最大的有點是如果子類繼承了多個父類,它只需要使用一次super函數就可以。然而如果沒有這個需求,直接使用based.__init__(self)更直觀一些。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM