Python的三大特性

封装

封装的优点

1.使用起来更方便: 因为已经把很多的功能,封装成一个整体,类似于像外界提供一个工具箱,针对于不同的场景,使用不同的工具箱就可以

2.保证数据安全: 针对于安全级别很高的数据,可以设置为"私有",可以控制数据为只读,外界无法修改,也可以拦截数据的写操作,进行数据校验和过滤

3.利于代码的维护: 如果后期代码功能需要维护,则直接修改这个类内部代码即可,只要保证接口名称不变;外界不需要做任何代码修改

 

继承

 

#--------------继承-资源-------------
class Animal:
    #属性和方法
    #设置不同权限的属性和方法,继承当中进行测试
    #在子类当中,能否访问到这些资源
    a = 1
    _b = 2
    __c = 3
    def aa(self):
        print("aa")
    def _bb(self):
        print("aa")
    def __cc(self):
        print("aa")
    def  __init(self):
        print("Animal内置初始化")

#继承
class Dog(Animal):
    def test(self):
        print(self.a)
        print(id(self.a))
        print(self._b)
        # print(self.__c) #不能访问
        self.aa()
        self._bb()
        # self.__cc()  #不能访问

d = Dog()
d.test()

#只能使用,不能拥有
print(id(Animal.a))
d.test()
资源继承

当子类和父类有相同资源的时候,调用子类的资源使用的到底是谁的资源问题,深度优先,然后广度优先原则

 

 经典类:深度优先 Python2.2以后的新式类中在深度优先(从左到右)的算法的基础上,优化了一部分,如果产生重复元素,会保留最后一个,并且,更最终基类出现的先后顺序

#---------有重叠继承链--------

class D:
    age = 'd'
class C(D):
    age = 'c'
class B(D):
    age = 'b'
class A(B,C):
    age = 'a'

print(A.age)
有重叠继承链
#---------无重叠继承链--------
class E:
    age = 'e'
class D:
    age = 'd'
class C(E):
    age = 'c'
class B(D):
    age = 'b'
class A(B,C):
    age = 'a'

print(A.age)
无重叠继承
#单继承链
class C:
    # age = 'c'
    pass

class B(C):
    # age = 'b'
    pass

class A(B):
    # age = 'a'
    pass

print(A.age)
单继承链

 使用inspect模块进行查询继承顺序关系,也可以使用"类.__mro__"或者mro(类)方法查看

#---------有重叠继承链--------
import inspect
class D:
    age = 'd'
class C(D):
    age = 'c'
class B(D):
    age = 'b'
class A(B,C):
    age = 'a'

print(A.age)
print(inspect.getmro(A))
inspect查询

当继承关系如下图所示:就会产生继承堆叠,当A继承C的时候就继承了BD和object,当B被继承就产生叠加的部分

 

#------------------继承-资源的访问顺序-2.3-2.7 C3算法---------
#经典类:深度原则(堆栈方式)
#新式类:广度原则(队列方式)
class D(object):
    pass
class B(D):
    pass
class C(D):
    pass
class A(B,C):
    pass

import inspect
print(inspect.getmro(A))
Python C3算法(未完成)

 资源的累加

class B:
    a = 1
    def __init__(self):
        self.b = 2

    def t1(self):
        print("B的t1方法")

    @classmethod #类方法,传入的参数为类
    def t2(cls):
        print("B的t2方法")

    @staticmethod  #静态方法
    def t3():
        print("B的t3方法")

class A(B):
    c = 3
    def __init__(self):
        self.e = '666'
        #父类名称变化后不利于维护,这种调用方法需要修改名称
        #菱形继承的时候有时候还会引用重复的情况
        B.__init__(self) #此self是A的实例对象

    def tt1(self):
        print("B的t1方法")

    @classmethod #类方法,传入的参数为类
    def tt2(cls):
        print("B的t2方法")

    @staticmethod  #静态方法
    def tt3():
        print("B的t3方法")

a = A()
print(a.__dict__)
资源累加
#---------------------资源的累加------------
# 1.直接复制方法到A,维护性差
# 2.B实例化方法传递给A,不可取,根据查找优先级会先查找自己的实例对象下的方法
# 3.使用super(仅仅新式类使用),沿着MRO链条进行继承
'''
##super原理:
    super(参数1,参数2)
    def super(cls,inst):
        mro = inst.__class__.mro()
        return mro[mro.index(cls)+1]
沿着参数2的MRO链条,找参数1的下一个节点
##写法
    super().__init__()是Python3.x的写法,自动填充super(__class__,<first argument>)
'''
import inspect
class B:
    a = 1
    def __init__(self):
        self.b = 2
        print("类名:",self.__class__.__name__)

    def t1(self):
        print("B的t1方法")

    @classmethod #类方法,传入的参数为类
    def t2(cls):
        print("B的t2方法")

    @staticmethod  #静态方法
    def t3():
        print("B的t3方法")

class A(B):
    c = 3
    def __init__(self):
        self.e = '666'
        #父类名称变化后不利于维护,这种调用方法需要修改名称
        #菱形继承的时候有时候还会引用重复的情况
        # B.__init__(self) #此self是A的实例对象
        # super().__init__()  #仅仅Python3.x的写法,自动填充
        super(A,self).__init__() #将A的对象传入到B的初始化方法中
    def tt1(self):
        print("B的t1方法")

    @classmethod #类方法,传入的参数为类
    def tt2(cls):
        print("B的t2方法")

    @staticmethod  #静态方法
    def tt3():
        print("B的t3方法")

a = A()
print(inspect.getmro(A))
mro = a.__class__.mro()
print(mro[mro.index(A)+1])
super原理

super(cls,ins):super方法是按照cls确定一个mro链,根据这个mro链将ins进行传递

#--------菱形继承重复调用使用super解决---
#=============引用重复======
# class D(object):
#     def __init__(self):
#         print("d")

# class B(D):
#     def __init__(self):
#         D.__init__(self)
#         print("b")

# class C(D):
#     def __init__(self):
#         D.__init__(self)
#         print("c")

# class A(B,C):
#     def __init__(self):
#         B.__init__(self)
#         C.__init__(self)
#         print("a")

# A()
#===============使用super====
'''切记参数super(self.__class__,self)不能这样写
   当上一个链传入的时候可能不是本方法的类和实例对象
'''
#super(cls,ins),super方法是按照cls确定一个mro链,根据这个mro链将ins进行传递
class D(object):
    def __init__(self):
        print("d",self.__class__.__name__)

class B(D):
    def __init__(self):
        super(B,self).__init__()
        print("b",self.__class__.__name__)

class C(D):
    def __init__(self):
        super(C,self).__init__() #self本实例对象传入到继承中的初始方法
        print("c",self.__class__.__name__)

class A(B,C):
    def __init__(self):
        # B.__init__(self)
        # C.__init__(self)
        #super第一个参数的下一个mro是B
        #super的第二个参数是传入到B的初始化方法中
        super(A,self).__init__()
        print("a",self.__class__.__name__)

A()
print(A.mro()) #A-->B-->C-->D
super原理(深刻)

 

多态

一个类所延伸的多种形,调用时的多种形态

#========================多态=======
# 多态: 一个类所延伸的多种形,调用时的多种形态
# 一般编程语言需要在继承的前提下;使用不同的子类,调用父类的同一个方法,产生不同的功能
# 而Python没有真正的多态,只关注有没有其方法,不在于对象类型
class Animal:
    pass
class Cat(Animal):
    def bark(self):
        print("喵喵猫")

class Dog(Animal):
    def bark(self):
        print("汪汪汪")

def duotai(obj):
    obj.bark()

c = Cat()
d = Dog()
duotai(c)
多态

抽象类:一个抽象出来的类,并不是某一个具化的类,不能直接创建实例的类,创建会报错

抽象方法:抽象出来的一个方法,不具备具体实现,不能直接调用,子类不实现会报错

应用:在写代码的时候,有时候必须实现的方法在多人合作的时候就可以使用抽象类和抽象方法

#========================抽象方法和抽象类=======
#抽象类:一个抽象出来的类,并不是某一个具化的类,不能直接创建实例的类,创建会报错
#抽象方法:抽象出来的一个方法,不具备具体实现,不能直接调用,子类不实现会报错

import abc #抽象模块
class Animal(object,metaclass=abc.ABCMeta): #变为抽象类,不能实例化
    @abc.abstractmethod #抽象方法,子类必须实现此方法
    def bark():
        pass
    @abc.abstractclassmethod #抽象类方法,子类必须实现此方法
    def test(cls):
        pass

class Cat(Animal):
    def bark(self):
        print("喵喵猫")
    @classmethod
    def test(cls):
        print("毛毛")

class Dog(Animal):
    def bark(self):
        print("汪汪汪")
    @classmethod
    def test(cls):
        print("晃晃")

def duotai(obj):
    obj.bark()
    obj.test()

c = Cat()
d = Dog()
duotai(c)
抽象类和抽象方法

 

实践作业

#定义三个类,小狗,小猫,人I#小狗:姓名,年龄(默认1岁);
#吃饭,玩,睡觉,看家(格式:名字是xx,年龄xx岁的小狗在xx)
#小猫:姓名,年龄(默认1岁);
#吃饭,玩,睡觉,捉老鼠(格式:名字是xx,年龄xx岁的小猫在xx)
#人:姓名,年龄(默认1岁),宠物;吃饭,玩,睡觉(格式:名字是xx,年龄xx岁的小猫在xx)
#
# 养宠物(让所有的宠物吃饭,玩,睡觉)#
# 让宠物工作(让所有的宠物根据自己的职责开始工作)
class Person:
    #在创建一个小狗的实例的时候,给他设置几个属性
    def __init__(self,name,pets,age=1):
        self.name = name
        self.age = age
        self.pets = pets

    def eat(self):
        # print("名字是{},年龄{}岁的小狗在吃饭".format(self.name,self.age))
        print("%s在吃饭"%self)

    def play(self):
        # print("名字是{},年龄{}岁的小狗在玩耍".format(self.name,self.age))
        print("%s在玩耍"%self)

    def sleep(self):
        # print("名字是{},年龄{}岁的小狗在睡觉".format(self.name,self.age))
        print("%s在睡觉"%self)

    def make_pet_work(self):
        for pet in self.pets:
            if isinstance(pet,Dog):
                pet.watch()
            elif isinstance(pet,Cat):
                pet.catch()

    def __str__(self):  #实例对象的字符串
        return "名字是{},年龄{}岁的小狗".format(self.name,self.age)

    def yangPets(self):
        for pet in self.pets:
            pet.eat()
            pet.play()
            pet.sleep()

class Dog:
    #在创建一个小狗的实例的时候,给他设置几个属性
    def __init__(self,name,age=1):
        self.name = name
        self.age = age

    def eat(self):
        # print("名字是{},年龄{}岁的小狗在吃饭".format(self.name,self.age))
        print("%s在吃饭"%self)

    def play(self):
        # print("名字是{},年龄{}岁的小狗在玩耍".format(self.name,self.age))
        print("%s在玩耍"%self)

    def sleep(self):
        # print("名字是{},年龄{}岁的小狗在睡觉".format(self.name,self.age))
        print("%s在睡觉"%self)

    def watch(self):
        print("%s在看家"%self)

    def __str__(self):  #实例对象的字符串
        return "名字是{},年龄{}岁的小狗".format(self.name,self.age)

class Cat:
    #在创建一个小狗的实例的时候,给他设置几个属性
    def __init__(self,name,age=1):
        self.name = name
        self.age = age

    def eat(self):
        # print("名字是{},年龄{}岁的小狗在吃饭".format(self.name,self.age))
        print("%s在吃饭"%self)

    def play(self):
        # print("名字是{},年龄{}岁的小狗在玩耍".format(self.name,self.age))
        print("%s在玩耍"%self)

    def sleep(self):
        # print("名字是{},年龄{}岁的小狗在睡觉".format(self.name,self.age))
        print("%s在睡觉"%self)

    def catch(self):
        print("%s在抓老鼠"%self)

    def __str__(self):  #实例对象的字符串
        return "名字是{},年龄{}岁的小狗".format(self.name,self.age)

d = Dog("小黑",18)
c = Cat("小红",2)
p = Person("高达",[d,c],18)
p.yangPets()
p.make_pet_work()
源代码

但是上述的三个类别中有相同的方法也有不同的方法,我们使用继承方法进行优化代码

#定义三个类,小狗,小猫,人I#小狗:姓名,年龄(默认1岁);
#吃饭,玩,睡觉,看家(格式:名字是xx,年龄xx岁的小狗在xx)
#小猫:姓名,年龄(默认1岁);
#吃饭,玩,睡觉,捉老鼠(格式:名字是xx,年龄xx岁的小猫在xx)
#人:姓名,年龄(默认1岁),宠物;吃饭,玩,睡觉(格式:名字是xx,年龄xx岁的小猫在xx)
#
# 养宠物(让所有的宠物吃饭,玩,睡觉)#
# 让宠物工作(让所有的宠物根据自己的职责开始工作)
class Animal:
    def __init__(self,name,age=1):
        self.name = name
        self.age = age

    def eat(self):
        # print("名字是{},年龄{}岁的小狗在吃饭".format(self.name,self.age))
        print("%s在吃饭"%self)

    def play(self):
        # print("名字是{},年龄{}岁的小狗在玩耍".format(self.name,self.age))
        print("%s在玩耍"%self)

    def sleep(self):
        # print("名字是{},年龄{}岁的小狗在睡觉".format(self.name,self.age))
        print("%s在睡觉"%self)


class Person(Animal):
    #在创建一个小狗的实例的时候,给他设置几个属性
    def __init__(self,name,pets,age=1): #传入的参数
        super(Person,self).__init__(name,age) #继承父类的初始化 name和age传入到继承类的初始化方法中
        self.pets = pets

    
    def make_pet_work(self):
        for pet in self.pets:
            if isinstance(pet,Dog):
                pet.watch()
            elif isinstance(pet,Cat):
                pet.catch()

    def __str__(self):  #实例对象的字符串
        return "名字是{},年龄{}岁的小狗".format(self.name,self.age)

    def yangPets(self):
        for pet in self.pets:
            pet.eat()
            pet.play()
            pet.sleep()

class Dog(Animal):
    #在创建一个小狗的实例的时候,给他设置几个属性
    def watch(self):
        print("%s在看家"%self)

    def __str__(self):  #实例对象的字符串
        return "名字是{},年龄{}岁的小狗".format(self.name,self.age)

class Cat(Animal):
    #在创建一个小狗的实例的时候,给他设置几个属性

    def catch(self):
        print("%s在抓老鼠"%self)

    def __str__(self):  #实例对象的字符串
        return "名字是{},年龄{}岁的小狗".format(self.name,self.age)

d = Dog("小黑",18)
c = Cat("小红",2)
p = Person("高达",[d,c],18)
p.yangPets()
p.make_pet_work()
优化代码

 

posted @ 2022-11-04 21:15  Crown-V  阅读(352)  评论(0)    收藏  举报