zoukankan      html  css  js  c++  java
  • 《Effective Python》笔记——第3章 类与继承

    一、尽量用辅助类来维护程序的状态

    如下,用字典存储简单数据

    class SimpleGradebook():
        def __init__(self):
            self.__grades = {}
    
        def add_student(self, name):
            self.__grades[name] = []    # 一个学生对应一个成绩列表
    
        def report_grade(self, name, score):
            self.__grades[name].append(score)
    
        def average_grade(self, name):
            grades = self.__grades[name]
            return sum(grades) / len(grades)    # 计算一个学生的平均成绩
    
    
    book = SimpleGradebook()
    book.add_student('ss')
    book.report_grade('ss', 90)
    book.report_grade('ss', 100)
    print(book.average_grade('ss'))

    如下示例,多层字典结构,代码变得负责且难读

    class SimpleGradebook():
        def __init__(self):
            self.__grades = {}
    
        def add_student(self, name):
            self.__grades[name] = {}    # 一个学生的成绩加入科目分类,所以用字典存储
    
        def report_grade(self, name, subject, score):
            by_subject = self.__grades[name]
            grade_list = by_subject.setdefault(subject, [])     # 存在该科目则返回已有列表,不存在则返回一个空列表
            grade_list.append(score)
    
        def average_grade(self, name):
            by_subject = self.__grades[name]
            total, count = 0, 0
            for grades in by_subject.values():
                total += sum(grades)
                count += len(grades)
            return total / count
    
    
    book = SimpleGradebook()
    book.add_student('ss')
    book.report_grade('ss', 'Math', 90)
    book.report_grade('ss', 'Math', 100)
    print(book.average_grade('ss'))

    使用嵌套结构重构类,书上的代码有错,以下是github上本书第二版的最新示例代码

    from collections import namedtuple, defaultdict
    
    Grade = namedtuple('Grade', ('score', 'weight'))    # 具名元组
    
    
    class Subject:
        # 科目的类,包含成绩和权重
        def __init__(self):
            self._grades = []
    
        def report_grade(self, score, weight):
            self._grades.append(Grade(score, weight))
    
        def average_grade(self):
            total, total_weight = 0, 0
            for grade in self._grades:
                total += grade.score * grade.weight
                total_weight += grade.weight
            return total / total_weight
    
    
    class Student:
        # 学生的类,包含各项课程
        def __init__(self):
            self._subjects = defaultdict(Subject)
    
        def get_subject(self, name):
            return self._subjects[name]
    
        def average_grade(self):
            total, count = 0, 0
            for subject in self._subjects.values():
                total += subject.average_grade()
                count += 1
            return total / count
    
    
    class Gradebook:
        # 所有学生成绩的容器类,以学生的名字为键
        def __init__(self):
            self._students = defaultdict(Student)
    
        def get_student(self, name):
            return self._students[name]
    
    
    book = Gradebook()
    albert = book.get_student('ss')
    math = albert.get_subject('Math')
    math.report_grade(75, 0.05)
    math.report_grade(65, 0.15)
    math.report_grade(70, 0.80)
    gym = albert.get_subject('Gym')
    gym.report_grade(100, 0.40)
    gym.report_grade(85, 0.60)
    print(albert.average_grade())

    二、简单接口应该接受函数,而不是类的实例

     简单接口使用函数,不要用类;

    通过__call__方法,可以使类实例像函数一样被调用

    如果需要保存状态,应该定义新的类,而不是带状态的闭包。

    三、以@classmethod形式的多态去通用地构建对象

     pass

    四、用super初始化父类

    pass

    五、多用public属性,少用private属性

    pass

    六、从collections.abc中继承基类

    简单子类可以直接从python的标准类型中继承(如list,dict,set,tuple等)

    collections.abc中有很多基类

  • 相关阅读:
    UNIT THREE
    UNIT TWO
    UNIT ONE
    实验九 根据材料编程
    实验五 编写、调试具有多个段的程序
    实验 四 [bx]和loop的使用
    实验二 用机器指令和汇编指令编程
    实验三 编程、编译、连接、跟踪
    实验一 查看CPU和内存,用机器指令和汇编指令编程
    汇编语言第5~8章知识总结
  • 原文地址:https://www.cnblogs.com/maxgongzuo/p/11067001.html
Copyright © 2011-2022 走看看