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

 

posted on 2017-07-05 22:56  lucaq  阅读(605)  评论(0编辑  收藏  举报

导航