抽象类:本身不能被实例化,也不应该不实例化,它的作用就定义标准,并不用具体实现
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
时间: 2024-08-07 12:25:15