内容回顾
1、封装=》整合
人的对象.属性
2、隐藏属性
__属性__
1、这种隐藏只是一种语法意义上的变形操作
2、这种变形是在检测类体语法的时候发生的,在这之后定义的__开头的属性不会发生变形
3、这种隐藏对外不对内
class Foo:
__x=111
def __init__(self,y):
self.__y=y
def func(self):
self.__y
def __f2(self):
pass
Foo.__xxx=222
obj=Foo()
obj.__z=333
今日内容:
1、property
2、继承介绍
python支持多继承
优点
缺点
新式类与经典类
3、如何找出继承关系-》抽象
4、属性查找顺序
类.y
obj.x
5、继承的实现原理
MRO
菱形问题/钻石问题
多继承背景下的属性查找探讨
property
"""
成人的BMI数值:
过轻:低于18.5
正常:18.5-23.9
过重:24-27
肥胖:28-32
非常肥胖, 高于32
体质指数(BMI)=体重(kg)÷身高^2(m)
EX:70kg÷(1.75×1.75)=22.86
"""
class People:
def __init__(self, name, weight, height):
self.name = name
self.weight = weight
self.height = height
@property
def bmi(self):
return self.weight / (self.height ** 2)
obj1 = People('egon', 70, 1.83)
print(obj1.bmi())
obj1.height = 1.86
print(obj1.bmi())
print(obj1.bmi)
class People:
def __init__(self, name):
self.__name = name
def get_name(self):
return self.__name
def set_name(self, val):
if type(val) is not str:
print('必须传入str类型')
return
self.__name = val
def del_name(self):
print('不让删除')
name = property(get_name, set_name, del_name)
obj1 = People('egon')
print(obj1.name)
class People:
def __init__(self, name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter
def name(self, val):
if type(val) is not str:
print('必须传入str类型')
return
self.__name = val
@name.deleter
def name(self):
print('不让删除')
obj1 = People('egon')
print(obj1.name)
obj1.name = 18
del obj1.name
继承
class Parent1(object):
x = 1111
class Parent2(object):
pass
class Sub1(Parent1):
pass
class Sub2(Parent1, Parent2):
pass
print(Sub1.__bases__)
print(Sub2.__bases__)
print(Sub1.x)
class Student:
school = 'OLDBOY'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
def choose_course(self):
print('学生%s 正在选课' % self.name)
class Teacher:
school = 'OLDBOY'
def __init__(self, name, age, sex, salary, level):
self.name = name
self.age = age
self.sex = sex
self.salary = salary
self.level = level
def score(self):
print('老师 %s 正在给学生打分' % self.name)
class OldboyPeople:
school = 'OLDBOY'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class Student(OldboyPeople):
def choose_course(self):
print('学生%s 正在选课' % self.name)
stu_obj = Student('lili', 18, 'female')
print(stu_obj.__dict__)
print(stu_obj.school)
stu_obj.choose_course()
class Teacher(OldboyPeople):
def __init__(self, name, age, sex, salary, level):
OldboyPeople.__init__(self, name, age, sex)
self.salary = salary
self.level = level
def score(self):
print('老师 %s 正在给学生打分' % self.name)
tea_obj = Teacher('egon', 18, 'male', 3000, 10)
print(tea_obj.__dict__)
print(tea_obj.school)
tea_obj.score()
属性查找
class Foo:
def f1(self):
print('Foo.f1')
def f2(self):
print('Foo.f2')
self.f1()
class Bar(Foo):
def f1(self):
print('Bar.f1')
obj = Bar()
obj.f2()
class Foo:
def f1(self):
print('Foo.f1')
def f2(self):
print('Foo.f2')
Foo.f1(self)
class Bar(Foo):
def f1(self):
print('Bar.f1')
obj = Bar()
obj.f2()
class Foo:
def __f1(self):
print('Foo.f1')
def f2(self):
print('Foo.f2')
self.__f1()
class Bar(Foo):
def __f1(self):
print('Bar.f1')
obj = Bar()
obj.f2()
多继承带来的菱形问题
一:菱形问题介绍与MRO
class A(object):
pass
class B(A):
def test(self):
print('from B')
pass
class C(A):
pass
class D(C, B):
pass
print(D.mro())
class E:
pass
class F:
def test(self):
print('from F')
class B(E):
pass
class C(F):
pass
class D:
def test(self):
print('from D')
class A(B, C, D):
pass
obj = A()
obj.test()
三:如果多继承是菱形继承,经典类与新式类的属性查找顺序不一样:
经典类:深度优先,会在检索第一条分支的时候就直接一条道走到黑,即会检索大脑袋(共同的父类)
新式类:广度优先,会在检索最后一条分支的时候检索大脑袋
class G:
pass
class E(G):
pass
class F(G):
def test(self):
print('from F')
class B(E):
pass
class C(F):
def test(self):
print('from C')
class D(G):
def test(self):
print('from D')
class A(B, C, D):
pass
obj = A()
obj.test()
作业
作业一:自己试验一下菱形问题下的属性查找顺序
作业二:在昨天作业的基础之上
注意:要满足什么"是"什么的关系,不满足"是"的关系不要去继承
作业三:选做作业,本周内完成,在作业二的基础上编写业务逻辑
提供三个角色操作:
1 学员视图:可以注册, 交学费, 选择班级,
2 讲师视图:讲师可管理自己的班级, 上课时选择班级, 查看班级学员列表 , 修改所管理的学员的成绩
3 管理视图:创建讲师, 创建班级,创建课程