book_effective Python_59个有效办法(三)

类与继承

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

# Example 10
grades = []
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_weight
print(average_grade)
#把嵌套结构改写成类
# Example 12
class 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 13
class 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 14
class 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 15
book = 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 8
class BetterCountMissing(object):
    def __init__(self):
        self.added = 0

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

counter = BetterCountMissing()
counter()
assert callable(counter)

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

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

没看懂,先跳过

25 用super初始化父类

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

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

先跳过

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

比较简单,无需多言。

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

  • 如果定制的子类比较简单,可直接从Python的容器类型中继承
  • 编写自制的容器类型时,可从collections。abc模块的抽象基类中继承,那些基类能够确保我们的子类具备适当的接口及行为。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值