4.9作业

一. 试验一下菱形问题下的属性查找顺序

"""
查找顺序: 经典类深度优先, 新式类广度优先
提示1: 只有python2中有经典类的概念, python3中默认继承或不继承object都是新式类.
提示2: python2中没有继承object的类及其子类都没有"类名.mro()"方法, 只有继承了才有. 而python3因为无论有没有显示继承都是默认继承object类, 所以由"类名.mro()"方法.
提示3: 深度优先, 广度优先都是基于当前分支最终继承的非object类当作参考点. 如果时深度优先则会在第一分支下就回去找. 如果时广度优先则会在最后分支中去找.
"""
"""
class G(object):  # 在python2中,未继承object的类及其子类,都是经典类
    def test(self):
        print('from G')

    pass


class E(G):
    # def test(self):
    #     print('from E')

    pass


class F(G):
    # def test(self):
    #     print('from F')

    pass


class B(E):
    # def test(self):
    #     print('from B')

    pass


class C(F):
    # def test(self):
    #     print('from C')

    pass


class D(G):
    # def test(self):
    #     print('from D')

    pass


class A(B, C, D):
    # def test(self):
    #     print('from A')

    pass


# 新式类
# print(A.mro())  # A -> B -> E -> C -> F -> D -> G -> object

# 经典类: 要放到python2中执行.
# print(A.mro()) # A -> B -> E -> G -> C -> F -> D

obj = A()
obj.test()

二. 在昨天基础之上优化

# 优化需求:
"""
1. 引入属性访问控制+property
2. 引入继承与派生的概念来减少代码冗余
注意:要满足什么"是"什么的关系,不满足"是"的关系不要去继承
"""
import os
import uuid
import pickle


class Base:
    base_path = os.path.normpath(os.path.join(__file__, '..'))

    def save(self):
        dir_path = os.path.join(self.base_path, self.__class__.__name__.lower())
        if not os.path.isdir(dir_path):
            os.mkdir(dir_path)
        path = os.path.join(dir_path, self.uuid)
        with open(path, 'wb') as f:
            pickle.dump(self, f)

    @classmethod
    def select(cls, uuid_name):
        path = os.path.join(cls.base_path, cls.__name__.lower(), uuid_name)
        if not os.path.isfile(path):
            return
        with open(path, 'rb') as f:
            return pickle.load(f)

    @classmethod
    def get_uuid(cls):
        dir_path = os.path.join(cls.base_path, cls.__name__.lower())
        for uuid_name in os.listdir(dir_path):
            if os.path.isdir(uuid_name):
                continue
            yield cls.select(uuid_name)


class School(Base):
    __school_name = 'OldBoy'

    def __init__(self, addr):
        self.uuid = str(uuid.uuid1())
        self.addr = addr
        self.class_list = []

    def related_class(self, class_obj):
        self.class_list.append(class_obj)

    def tell_class(self):
        print(f'{self.__school_name}:{self.addr}'.center(50, '='))
        for class_obj in self.class_list:
            class_obj.tell_course()


class Class(Base):
    def __init__(self, name):
        self.uuid = str(uuid.uuid1())
        self.name = name
        self.course_obj = None
        self.student_list = []

    def related_course(self, course_obj):
        self.course_obj = course_obj

    def tell_course(self):
        print(f'班级:{self.name}', end=' ')
        print(self.course_obj)

    def tell_student(self):
        print(f'班级:{self.name}'.center(50, '='))
        for student_obj in self.student_list:
            print(student_obj)


class Course(Base):
    def __init__(self, name, period, price):
        self.uuid = str(uuid.uuid1())
        self.name = name
        self.period = period
        self.price = price

    def __str__(self):
        return f'<课程:{self.name} 周期:{self.period}月 价格:{self.price}元>'


class People:
    def __init__(self, name, age, sex='male'):
        self.name = name
        self.age = age
        self.sex = sex


class Student(Base, People):
    def __init__(self, name, age, sex='male'):
        People.__init__(self, name, age, sex)
        self.uuid = str(uuid.uuid1())
        self.id_card = None
        self.__score = None

    def choose_class(self, class_obj):
        id_card = max(range(len(class_obj.student_list) + 1))
        self.id_card = id_card + 1
        # class_obj.student_list.append(self)
        class_obj.student_list.append(self)

    @property
    def score(self):
        return self.__score

    @score.setter
    def score(self, score_value):
        if not isinstance(score_value, int):
            raise TypeError("对不起, 修改的成绩必须是整数!")
        if not (0 <= score_value <= 100):
            raise TypeError("对不起, 成绩输入范围:0~100")
        self.__score = score_value

    def __str__(self):
        if self.__score:
            score = f'成绩:{self.__score}分'
        else:
            score = ''
        return f'学号:{self.id_card} 姓名:{self.name} 年龄:{self.age}岁 性别:{self.sex} {score}'


class Teacher(Base, People):
    def __init__(self, name, age, salary, level, sex='male'):
        People.__init__(self, name, age, sex)
        self.uuid = str(uuid.uuid1())
        self.salary = salary
        self.level = level

    @staticmethod
    def modify_score(student_obj, score):
        student_obj.score = score


# 实例化学校对象
school_obj1 = School('上海校区')
school_obj2 = School('北京校区')
school_obj3 = School('深圳校区')

# 实例化班级对象
class_obj1 = Class('脱产14期')
class_obj2 = Class('脱产15期')
class_obj3 = Class('脱产16期')

# 实例化课程对象
course_obj1 = Course('python', 6, 21800)
course_obj2 = Course('linux', 5, 19800)
course_obj3 = Course('go', 6, 20800)

# 实例化学生对象
student_obj1 = Student('张晨', 23)
student_obj2 = Student('刘旭', 28)
student_obj3 = Student('朱斌成', 24)
student_obj4 = Student('王律盛', 25)
student_obj5 = Student('陈诚', 23, 'female')
student_obj6 = Student('刘洋', 18)

# 实例化话老师对象
teacher_obj1 = Teacher('egon', 18, 99999, 9)
teacher_obj2 = Teacher('tank', 17, 100000, 8)

# 学校对象关联班级
school_obj1.related_class(class_obj1)
school_obj2.related_class(class_obj2)
school_obj3.related_class(class_obj3)

# 班级对象关联课程
class_obj1.related_course(course_obj1)
class_obj2.related_course(course_obj2)
class_obj3.related_course(course_obj3)

# 学生对象选择班级
student_obj1.choose_class(class_obj1)
student_obj2.choose_class(class_obj2)
student_obj3.choose_class(class_obj3)
student_obj4.choose_class(class_obj1)
student_obj5.choose_class(class_obj2)
student_obj6.choose_class(class_obj3)

# 老师对象修学生成绩
teacher_obj1.modify_score(student_obj1, 99)
teacher_obj2.modify_score(student_obj2, 88)
teacher_obj1.modify_score(student_obj3, 77)
teacher_obj2.modify_score(student_obj4, 66)
teacher_obj1.modify_score(student_obj5, 55)
teacher_obj2.modify_score(student_obj6, 44)

"""
# 学校对象查看班级
school_obj1.tell_class()
school_obj2.tell_class()
school_obj3.tell_class()

# 班级对象查看学生
class_obj1.tell_student()
class_obj2.tell_student()
class_obj3.tell_student()
"""

# 保存以上所有对象到文件
"""
school_obj1.save()
school_obj2.save()
school_obj3.save()

class_obj1.save()
class_obj2.save()
class_obj3.save()

course_obj1.save()
course_obj2.save()
course_obj3.save()

student_obj1.save()
student_obj2.save()
student_obj3.save()
student_obj4.save()
student_obj5.save()
student_obj6.save()

teacher_obj1.save()
teacher_obj2.save()
"""

# 更具学校类名拿到学校下的所有文件对象并打印班级信息
for school_obj in School.get_uuid():
    school_obj.tell_class()

# 更具班级类名拿到班级下的所有文件对象并打印学生信息
for class_obj in Class.get_uuid():
    class_obj.tell_student()
原文地址:https://www.cnblogs.com/haliluyafeng/p/12670598.html