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

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

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

《Effective Python》笔记——第3章 类与继承的更多相关文章

  1. JVM学习笔记-第六章-类文件结构

    JVM学习笔记-第六章-类文件结构 6.3 Class类文件的结构 本章中,笔者只是通俗地将任意一个有效的类或接口锁应当满足的格式称为"Class文件格式",实际上它完全不需要以磁 ...

  2. [Effective JavaScript 笔记]第3章:使用函数--个人总结

    前言 这一章把平时会用到,但不会深究的知识点,分开细化地讲解了.里面很多内容在高3等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...

  3. C++ primer plus读书笔记——第13章 类继承

    第13章 类继承 1. 如果购买厂商的C库,除非厂商提供库函数的源代码,否则您将无法根据自己的需求,对函数进行扩展或修改.但如果是类库,只要其提供了类方法的头文件和编译后的代码,仍可以使用库中的类派生 ...

  4. C++ primer plus读书笔记——第12章 类和动态内存分配

    第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化 ...

  5. C#图解教程读书笔记(第7章 类和继承)

    1.所有的类都继承自object 2.如何隐藏基类的成员 要隐藏一个继承的数据成员,需要声明一个新的相同类型的成员,并使用相同的名称. 通过在派生类中声明新的带有相同签名的函数成员,可以隐藏或掩盖继承 ...

  6. python 静态方法,类方法 ,类的继承

    转自:  http://cowboy.1988.blog.163.com/blog/static/75105798201091141521583/ 1.关于定义类的一些奇特之处  今天在Python中 ...

  7. C#图解教程 第七章 类和继承

    类和继承 类继承访问继承的成员所有类都派生自object类屏蔽基类的成员基类访问使用基类的引用 虚方法和覆写方法覆写标记为override的方法覆盖其他成员类型 构造函数的执行 构造函数初始化语句类访 ...

  8. 【python系统学习14】类的继承与创新

    目录: 目录: [toc] 类的继承 子类和父类 继承的写法 继承示例 父类可以被无限个子类所继承 子类实例可调用父类属性和方法 类的始祖(根类) 根类 - object 实例归属判断 - isins ...

  9. [Effective Java 读书笔记] 第三章类和接口 第二十-二十一条

    第二十条 用函数对象表示策略 函数指针(JAVA的函数指针,是指使用对象的引用来作为参数,传递给另一个对象的方法)主要用来实现策略模式,为了在JAVA中实现这种模式,要申明一个接口来表示该策略,并为每 ...

随机推荐

  1. centos6.5-搭建Apache

    准备工作 1.关闭防火墙 service iptables stop 2.关闭selinux安全机制 setenforce 0 3.卸载rpm格式的httpd 这说明已经安装了rpm格式的软件包.所以 ...

  2. VUE3 之 键盘事件

    1. 概述 老话说的好:宁愿自己吃亏,也不让他人吃亏. 言归正传,今天我们来聊聊 VUE3 的 键盘事件. 2. 键盘事件 2.1 敲击任意键触发事件 <body> <div id= ...

  3. 如何用微信小程序,每天给自己赚个鸡腿?

    假期如果实在无聊的话,那跟随田同学的脚步上架一个小程序吧. 话说:谁不想拥有一个自己的小程序呢?既可以赚点小钱又可以长长见识. 不懂小程序的小白能不能做出来呢?那来对了,这个教程就是针对小白的. 今天 ...

  4. wordpress搭建网站更改域名后打开网页排版显示错乱解决办法

    发生的原因: 我本来已经搭建好了网站,也测试了没问题.后来更改了网站的域名,出现了这种情况. 解决办法: 需要修改数据库的options表里面的 siteurl 和 home 这两个表的内容为最新的域 ...

  5. 利用js模拟用户的cookie信息保存

    注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6814761849708347907/ 默认已完成爬虫文档<爬虫学习文档顺序> 并简单搭建完展示页面和管 ...

  6. 大厂面试来了,欢聚时代四年多经验的Java面经

    前言(也就是废话) 今年年底,额,不对,应该说是去年了,我开始进行了一个多月的面试之旅. 面试的公司并不多,但从体量上来看,基本算是一二三线的大厂都囊括了,其中还包括BAT,当然,最后我也是顺利的拿到 ...

  7. 【从小白到专家】 Istio专题之七:30分钟讲透Istio访问与控制

    本文为Istio系列专题之七--Istio访问与控制.Istio通过身份认证.授权.多重安全策略,来保证微服务的安全,实现代码无侵入性.有时我们需要对微服务间的相互访问进行控制,比如满足某些条件的微服 ...

  8. 一站式搭建 GitHub Pages 博客 (一)

    本文将详细讲解如何快速搭建 GitHub Pages 博客页面 关于博客主题,博客信息更改,上传文章等将会在 一站式搭建 GitHub Pages 博客 (二) 中进行详细讲解 准备阶段 注册 Git ...

  9. 通过Javascript实现把数组里的内容以表格方式呈现到页面从

    一.把数组里的内容呈现到页面从,以表格方式 <!doctype html> <html> <head> <meta charset="utf-8&q ...

  10. linux与shell介绍 - 进程与线程

    linux linux与windows的区别 linux的文件结构 Linux基本命令 ls: 列出目录 cd: 切换目录 pwd: 显示当前目录 mkdir: 创建一个新的目录 rmdir: 删除一 ...