当前位置:首页 > Python教程 > python技巧

Python 继承

何为继承?

继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类。

先举一个例子,如:

            class
             animal:
    
            def
            __init__
            (self,name,kind,food,language):
        self.name = name
        self.kind = kind
        self.food = food
        self.language = language
    def yell(self):
        print(%s叫 % self.language)
    def eat(self):
        print(吃%s % self.food)
    def drink(self):
        print(喝水)
class cat(animal):
    def catch_mouse(self):
        print(抓老鼠)
class dog(animal):
    def look_after_house(self):
        print(看家)
Ali = cat(Ali, bosi_cat, fish, miaomiao)
Jingang = dog(Jingang,aisijimo_dog, paigu, wangwang)
Ali.yell()
Ali.catch_mouse()
Ali.drink()
Jingang.yell()
Jingang.eat()
Jingang.look_after_house()

从上面可以看出,cat与dog类为子类,而animal为父类,当实例化cat类调用yell方法时,首先会去子类中寻找,当找不到时,再去父类中寻找,从而调用。实例化dog类也是一样。

            class
             animal:
    
            def
            __init__
            (self, name, kind, food, language):
        
            #
             print(‘in animal‘)
        self.name = name
        self.king = kind
        self.food = food
        self.language = language
    def yell(self):
        print(%s叫% self.language)
    def eat(self):
        print(吃%s % self.food)
    def drink(self):
        print(喝水)

class cat(animal):

    def__init__(self, name, kind, food, language, eye_color):
        # print(‘in cat‘)
        self.eye_color = eye_color   # 派生类属性# animal.__init__(self, name, kind, food, language)   # 调用父类的方法
        super().__init__(name,kind,food,language)    # 调用父类 __init__def catch_mouse(self):
        print(抓老鼠)
    def eat(self):        # 不仅执行了父类中的基础功能,还完成了特殊的功能        animal.eat(self)
        super().eat()
        self.weight = 10   # 方法内定义属性class dog(animal):
    def look_after_house(self):
        print(看家)
    def eat(self):
        animal.eat(self)
        super().eat()
        self.drink()
Ali = cat(Ali, bosi_cat, fish, miaomiao,绿色)
print(Ali.food)
Ali.eat()
Ali.catch_mouse()
print(Ali.weight)

从上面分析可知:

当子类当中有被调用的方法时,子类的对象会直接选择子类中的方法,变量,父类中的方法不会被自动执行

如果我们既要想执行子类方法,又想执行父类的方法,那么需要在子类的方法中调用父类的方法:

父类名.方法名(self,...(参数))super().方法名((没有self)...(参数))

上面使用的好处:可以帮助我们在子类中调用父类中的同名方法

面试题:

下面几道题为面试常考题,进行分析下:

            #
             例1
            class
             Foo:
    
            def
            __init__
            (self):
        self.func()
    
            def
             func(self):
        
            print(in Foo)

class Son(Foo):
    def func(self):
        print(in Son)

s1 = Son()    # in Son
        # 解题思路:
        
1 将Son类实例化给s1
2 在son类中寻找__init__方法,如果没有,就去父类Foo中寻找
3 自动执行父类中的__init__方法,此时,self始终为s1,因此,该内部调用的方法为:s1.func()
4 返回到Son类中,打印输出‘in Son‘
            #
             例2:
            class
             Foo:
    Country = Chinadef func(self):
        print(self.Country)

class Son(Foo):
    Country = Englishdef func(self):     # 走这个方法print(self.Country)

s = Son()
s.func()   # English
            #
             例3:
            class
             Foo:
    Country = Chinadef func(self):  # 走这个方法print(self.Country)

class Son(Foo):
    Country = English

s = Son()
s.func()   # English
        # 解题思路:
        
1 实例化对象s,开辟类对象空间存储属性 即Country = ‘English‘
2 调用子类空间func()函数,若没有,去父类去寻找,
3 此时父类中的self为实例化对象s,因此,打印输出的为:English
            #
             例4:
            class
             Foo:
    Country = Chinadef func(self):
        print(self.Country)

class Son(Foo):pass

s = Son()
s.func()   # ‘China‘
        解题思路:
        
1 同上,子类中没有属性与方法
2 调用父类属性与方法,进行输出
多继承

什么是多继承?多继承可表示为:

            class Parent1:passclass Parent2:passclass Son(Parent1,Parent2):passprint(Son.__bases__)    # (<class ‘__main__.Parent1‘>, <class ‘__main__.Parent2‘>)

上式中,Son类为子类,父类为:Parent1与Parent2。在该继承方式中,Son类同时继承了两父类其查询方式又是怎样的呢?

            class
             F1:
    
            def
             a(self):
        
            print(F1.a)
class F2:
    def a(self):
        print(F2.a)
class S(F1,F2):
    pass
obj = S()
obj.a()   # F1.a
            class
             F0:
    
            def
             a(self):
        
            print(F0.a)

class F1(F0):
    def a1(self):
        print(F1.a)
class F2:
    def a(self):
        print(F2.a)
class S(F1,F2):
    pass
obj = S()
obj.a()   # F0.a
        运行下查找顺序:
        
python中支持多继承
a. 左侧优先
b. 一条道走到黑
c. 有同一个根时,根最后执行
            class
             Base():
    
            def
             a(self):
        
            print(Base.a)

class F0(Base):
    def a(self):
        print(F0.a)

class F1(F0):
    def a1(self):
        print(F1.a)

class F2(Base):
    def a(self):
        print(F2.a)

class S(F1,F2):
    pass

obj = S()
obj.a()

再举一个例子:

            class
             RequestHandler():
    
            def
             serve_forever(self):
        
            print(RequestHandler.serve.forever)
        self.process_request()
    def process_request(self):
        print(process_request.process_request)

class Minx:
    def process_request(self):
        print(minx.process_request)

class Son(Minx, RequestHandler):
    pass

obj = Son()
obj.serve_forever()

说明:

        函数内部self 指的就是对象obj。因此,在调用obj.serve_forever()时候,首先在派生类Son中找有没有serve_forever()函数,
        
若没有,则去Son中的父类Minx类去找,也没有后,在返回到父类RequestHandler()中去找,找到后执行并打印,当运行到
self.process_request()函数时,此时self 不是RequestHandler()函数内部的process_request(self),而是obj对象的的self,
即Son类的self,因此,又得重新从派生类按顺序去寻找process_request()函数,最后在父类Minx中找到!
            class
             BaseRequest:
    
            def
            __init__
            (self):
        
            print(BaseRequest.init)

class RequestHandler(BaseRequest):
    def__init__(self):
        print(RequestHandler.init)
        BaseRequest.__init__(self)   # 执行父类的__init__(self)def serve_forever(self):
        print(RequestHandler.serve.forever)
        self.process_request()
    def process_request(self):
        print(process_request.process_request)

class Minx:
    def process_request(self):
        print(minx.process_request)

class Son(Minx, RequestHandler):
    pass

obj = Son()
        
            默认执行__init__(self)函数,因此在子类或着父类中按顺序寻找该函数
obj.serve_forever() # 上面执行完了,重新执行该语句

 

原文:https://www.cnblogs.com/colin1314/p/9551215.html


【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!