book_effective Python_59个有效办法(三)

来源:互联网 发布:东北电力大学 知乎 编辑:程序博客网 时间:2024/06/06 07:46

    • 类与继承
      • 尽量用辅助类来维护程序的状态而不要用字典和元组
      • 简单的接口应该接受函数而不是类的实例
      • 以classmethod形式的多态去通用地构建对象
      • 用super初始化父类
      • 只在使用Mix-in组件制作工具类时进行多重继承
      • 多用public属性少用private属性
      • 继承collectionsabc以实现自定义的容器类型

类与继承

尽量用辅助类来维护程序的状态,而不要用字典和元组

# Example 10grades = []grades.append((95, 0.45, 'Great job'))grades.append((85, 0.55, 'Better next time'))total = sum(score * weight for score, weight, _ in grades)  # 遍历三元素元组的列表total_weight = sum(weight for _, weight, _ in grades)average_grade = total / total_weightprint(average_grade)#把嵌套结构改写成类# Example 12class Subject(object):    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# Example 13class Student(object):    def __init__(self):        self._subjects = {}    def subject(self, name):        if name not in self._subjects:            self._subjects[name] = Subject()        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# Example 14class Gradebook(object):    def __init__(self):        self._students = {}    def student(self, name):        if name not in self._students:            self._students[name] = Student()        return self._students[name]# Example 15book = Gradebook()albert = book.student('Albert Einstein')math = albert.subject('Math')math.report_grade(80, 0.10)math.report_grade(80, 0.10)math.report_grade(70, 0.80)gym = albert.subject('Gym')gym.report_grade(100, 0.40)gym.report_grade(85, 0.60)print(albert.average_grade())

代码量增加了很多,但更容易理解。

  • 不要使用包含其他字典的字典和过长的元组
  • namedtuple
  • 复杂的字典,拆解为多个辅助类

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

函数是一级对象,可以被传递和引用,可以充当挂钩(hook)。

# Example 8class BetterCountMissing(object):    def __init__(self):        self.added = 0    def __call__(self):   #通过__call__方法,可以使类的实例能够像普通函数那样得到调用        self.added += 1        return 0counter = BetterCountMissing()counter()assert callable(counter)

如果要用函数来保存状态,那就应该定义新的类,并令其实现call方法。

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

没看懂,先跳过

25 用super初始化父类

主要是在多重继承中,考虑初始化顺序时使用吧。一般用不动

26 只在使用Mix-in组件制作工具类时进行多重继承

先跳过

27 多用public属性,少用private属性

比较简单,无需多言。

28 继承collections.abc以实现自定义的容器类型

  • 如果定制的子类比较简单,可直接从Python的容器类型中继承
  • 编写自制的容器类型时,可从collections。abc模块的抽象基类中继承,那些基类能够确保我们的子类具备适当的接口及行为。
阅读全文
0 0
原创粉丝点击