Python学习_13_继承和元类

时间:2021-08-29 12:59:00

继承

继承的含义就是子类继承父类的命名空间,子类中可以调用父类的属性和方法,由于命名空间的查找方式,当子类中定义和父类同名属性或者方法时,子类的实例调用的是子类中的属性,而不是父类,这就形成了python中的多态:

def SuperClass:
    def a_method:
        pass
def SubClass(SuperClass):
    def a_method:
        pass
obj = SubClass()
obj.a_method()

当obj调用一个方法时,先从a对象本身局部命名空间查找,然后到SubClass中查找,然后才到SuperClass中查找,任何一处找到该属性都会终止查找过程,所以上例中obj调用的a_method属于SubClass中的方法。再次看到python中的对象各种关系,其实都是命名空间的关系。 

Python同时支持多重继承,一个类可以继承自多个父类,而在多重继承的关系中,属性的查找方式是广度优先搜索(最开始是深度优先),即会从每个父类中按顺序搜索,如果没有找到则到第一个父类的所有父类中按顺序搜索,然后是第二个父类的所有父类,接着是第一个父类的第一个父类的所有父类。。。。。。这样的查找方式好处是,总是会从第一级的类中继承属性,实际寻找的时候一定要注意到顺序的问题。

元类

如果说类是创建实例的模板,那么元类就是创建类的模板,区别元类和父类的不同,元类只是定义了类的构造方法:__new__方法,如果没有指定元类,则从缺省元类type中调用该方法:

class ListMetaclass(type):
    def __new__(cls, name, bases, attrs): 
        attrs['add'] = lambda self, value: self.append(value)
        return type.__new__(cls, name, bases, attrs)
class MyList(list,metaclass=ListMetaclass):
    pass
print(ListMetaclass.__class__)

和类使用工厂函数来实例化对象不同的是,通过在类定义中使用metaclass来指明元类。通过__new__构造器方法,对MyList添加add属性,所以在ListMetaclass中并没有add属性。元类的本质是类,只是定义了特殊__new__方法的类。