zoukankan      html  css  js  c++  java
  • python3 uper(),继承实现原理,封装

    抽象类:本身不能被实例化,也不应该不实例化,它的作用就定义标准,并不用具体实现
    import abc
    class Parent(metaclass=abc.ABCMeta):
        x=1
        @abc.abstractmethod
        def foo(self):
            pass
        @abc.abstractmethod
        def bar(self):
            pass
    
    class Child(Parent):
        def foo(self):
            pass
        def bar(self):
            pass

    新式类与经典类在这种继承结构下,属性的查找顺序完全一样:从做到右,一个分支接着一个分支地找

    print(mro())    # 查看属性查找顺序,只在新式类中适用


    新式类的在这中继承结构下,属性的查找关系,H->E->B->F->C-G-D-A 广度优先
    经典类的在这中继承结构下,属性的查找关系H-E-B-A-F-C-G-D 深度优先

    子类调用父类的方法,uper()函数
    class People:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
        def foo(self):
            print('from parent')
    
    class Teacher(People):
        def __init__(self,name,age,sex,salary,level):
            # People.__init__(self,name,age,sex)  # 指名道姓地调用People类的__init__函数
    
            # 在python3中
            super().__init__(name,age,sex)  # 调用父类的__init__的功能,实际上用的是绑定方法
            # super()函数一般只用于继承一个父类,如果是多个父类,只能找一个,多个的话,还是用指名道姓的方法
            # 在python2中
            # super(Teacher,self).__init__(name,age,sex)
    
            self.salary = salary
            self.level = level
    
        def foo(self):
            super().foo()
            print('from child')
    
    t = Teacher('egon',18,'male',3000,10)
    print(t.name,t.age,t.sex,t.salary,t.level)
    t.foo()
    封装
    *封装数据
    *封装功能
    class Teacher:
        __school = 'oldboy' # _Teacher__school
        def __init__(self,name,salary):
            self.name = name
            self.__salary = salary
    
        def __foo(self):
            print('====>')
    t = Teacher('egon',3000)
    
    # python里面没有绝对的封装
    # print(t.__school)     # 不能调用
    print(Teacher.__dict__) # 查看后发现变形了
    print(t._Teacher__school)   #可以查看变形后的
    t._Teacher__foo()
    
    # 这种变形操作只在定义阶段发生
    Teacher.__N = 12345
    print(Teacher.__dict__) # 没有变形


    在类的外部,无法直接使用变形的属性,但是在类的内部可以直接使用
    class Teacher:
        __school = 'oldboy' # _Teacher__school
        def __init__(self,name,salary):
            self.name = name
            self.__salary = salary #self._Teacher__salary
    
        def foo(self):
            print('====>',self.__salary)    # 这里直接调用了,所以外部t.foo()有结果
    t = Teacher('egon',3000)
    
    print(t._Teacher__salary)
    t.foo()

    一个例子
    class A:
        def foo(self):
            print('from A.foo')
            self.__bar() #self._A__bar()
    
        def __bar(self): #_A__bar()
            print('from A.bar')
    
    class B(A):
        def __bar(self):  #_B__bar
            print('from B.bar')
        pass
    
    b = B()
    b.foo()

    封装应用

    class People:
        def __init__(self,name,age,sex,height,weight):
            self.__name = name
            self.__age = age
            self.__sex = sex
            self.__height = height
            self.__weight = weight
    
        def tell_name(self):
            print(self.__name)
    
        def set_name(self,val):
            if not isinstance(val,str):
                raise TypeError('名称必须为字符串类型')
            self.__name = val
    
        def tell_info(self):
            print('''
            ---------%s info--------
            NAME:%s
            AGE:%s
            SEX:%s
            HEIGHT:%s
            WEIGHT:%s
            ''' %(self.__name,
                  self.__name,
                  self.__age,
                  self.__sex,
                  self.__height,
                  self.__weight))
    
    egon = People('egon',18,'mail','178cm','70kg')
    egon.tell_name()
    egon.tell_info()
    egon.set_name('EGON')
    # egon.set_name(123)
    egon.tell_info()

    property的应用

    定义People类,将name,age,sex,height,weight属性都隐藏起来

    对外提供接口,可以访问人的详细信息

    对外提供访问姓名,修改姓名,删除姓名的接口,在修改姓名时加上类型检查

    对外提供接口,访问人的BMI指数,并且用property装饰

    class People:
        def __init__(self,name,age,sex,height,weight,permission=False):
            self.__name = name
            self.__age = age
            self.__sex = sex
            self.__height = height
            self.__weight = weight
            self.permission = permission
    
        @property
        def info(self):
            print('''
            ---------%s info--------
            NAME:%s
            AGE:%s
            SEX:%s
            HEIGHT:%s
            WEIGHT:%s
            ''' %(self.__name,
                  self.__name,
                  self.__age,
                  self.__sex,
                  self.__height,
                  self.__weight))
    
        @property
        def dmi(self):
            print(self.__weight / (self.__height ** 2))
    
        @property
        def name(self):
            print(self.__name)
            return self.__name
    
        @name.setter
        def name(self, val):
            if not isinstance(val, str):
                raise TypeError('must be str')
            self.__name = val
    
        @name.deleter
        def name(self):
            if not self.permission:
                raise PermissionError('do not del')
            del self.__name
    
    egon = People('egon',18,'mail',78,70)
    egon.info
    egon.dmi
    egon.info
    egon.name = 'EGON'
    # del egon.name
    egon.info
  • 相关阅读:
    互联网资源获取
    Linux tomcat安装
    Linux JDK安装
    Linux入门教程
    windows命令行 查看文件树结构
    Gitea搭建及使用
    Jenkins搭建及使用
    Linux 基础环境搭建
    SpringBoot
    JSON Web Token(JWT)学习
  • 原文地址:https://www.cnblogs.com/lucaq/p/7123949.html
Copyright © 2011-2022 走看看