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

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

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中有很多基类

最新文章

  1. Apache Lucene(全文检索引擎)—搜索
  2. 嵌入式Linux驱动学习之路(十九)触摸屏驱动、tslib测试
  3. css 文本显示点点点
  4. Ubuntu 15.10搭建IPSec L2TP服务器
  5. SpringMVC从入门到精通之第四章
  6. Sass学习之路(1)——Sass简介
  7. C#中out和ref之间的区别
  8. 英文VS2010安装中文版MSDN文档方法
  9. Python Tornado
  10. bzoj3144
  11. BZOJ3297: [USACO2011 Open]forgot
  12. 好博客分享 go需要运行容器? 不需要
  13. 实验时css层叠样式表不更新的情况
  14. 【原创】poj ----- 1611 The Suspects 解题报告
  15. Java多线程:死锁
  16. 免费获取SSL证书/一键安装SSL证书/https加密
  17. 周报数据采集之生存图片(execl方法)
  18. python 验证码识别
  19. Json数组对象取值
  20. AndroidStudio工具将Module项目导出成Jar和arr库

热门文章

  1. golang 开源代理
  2. oracle 之 EXP、IMP 使用简介
  3. nginxWebUI
  4. Java数据类型 long 与 Long 的区别 和 正确用法
  5. ssh到localhost或127.0.0.1拒绝连接
  6. HIVE理论学习笔记
  7. STM32 EXTI(外部中断)
  8. Keil MDK STM32系列(五) 使用STM32CubeMX创建项目基础结构
  9. Genymotion安装apk问题
  10. elasticsearch拼写纠错之Term Suggester