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

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

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. Storm集群安装Version1.0.1开启Kerberos

    Storm集群安装,基于版本1.0.1, 同时开启Kerberos安全认证, 使用apache-storm-1.0.1.tar.gz安装包. 1.安装规划 角色规划 IP/机器名 安装软件 运行进程 ...

  2. win10快捷方式小箭头怎么去掉

    为了演示,先来看看桌面图标是有小箭头的. 1.打开注册表 按下快捷键"win+R",然后输入"regedit",并点击确认按钮. 2.搜索HKEY_CLASSE ...

  3. [Flask] 安装virtualenv时候出现的问题

    1.HTTPError: 404 Client Error: Not Found for url: ...的错误 ubuntu@VM-0-6-ubuntu:~/myprojects$ virtuale ...

  4. nuxt写路由接口

    //在server/interface/city.js import Router from 'koa-router'; const router = new Router({ prefix:'/ci ...

  5. Servlet初级学习加入数据库操作(三)

    源代码地址(访问密码:7567):https://url56.ctfile.com/f/34653256-527822631-2e255a CRUD 增删改查 准备添加的操作 点击添加之后,出现新的页 ...

  6. 用jquery实现省市联动

    <!-- 需求: [1] 动态生成省份选择框. [2] 当选择了省份的某一项时, 动态改变 城市选择中的列表项. --> <!DOCTYPE html> <html la ...

  7. POJ prime distance

    https://oj.shiyancang.cn/Problem/781.html 素数距离,数据范围21亿,如果用素数筛存,并且进行做的话,按照x/lnx计算会是一个非常恐怖的复杂度.确定要做什么, ...

  8. weblogic 未授权命令执行漏洞(CVE-2020-14882,CVE-2020-14883)复现

    漏洞描述 2020年10月29日,360CERT监测发现 Weblogic ConSole HTTP 协议代码执行漏洞,该漏洞编号为 CVE-2020-14882,CVE-2020-14883 ,漏洞 ...

  9. Android官方文档翻译 十二 3.Supporting Different Devices

    Supporting Different Devices 支持不同设备 Dependencies and prerequisites 依赖关系和先决条件 Android 1.6 or higher A ...

  10. Visual Studio 2015 MFC之Button颜色变化-断点调试(Debug)

    软件开发,对自己的程序进行调试很重要,本次文章在上一边随笔的基础上,介绍一下Button控件做显示灯的用法,Button控件的添加和变量设置等可以参考下面的的链接:Visaul Studio 2015 ...