zoukankan      html  css  js  c++  java
  • 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)更直观一些。

  • 相关阅读:
    android 源码编译 问题 列表
    springboot总结
    设计模式学习笔记
    JWT入门1
    oauth2入门github
    mybatis面试题
    shiro入门
    knife4j swagger API文档
    pahole安装(编译)
    goMySql的逆向工程
  • 原文地址:https://www.cnblogs.com/liunian1004/p/4551360.html
Copyright © 2011-2022 走看看