(一)从记录与函数到类和实例
1. 把处理一条记录的操作放在一起
先用已经会写的形式,处理两本书:
# 两个字典保存两条独立记录,函数通过参数确定修改哪一本。
def finish_book(book):
book["finished"] = True
first = {"title": "Python", "finished": False}
second = {"title": "NumPy", "finished": False}
finish_book(first)
print(first["finished"], second["finished"])输出 True False。数据与操作已经能配合。接下来把这套固定字段和操作写成一个类:
# class 建立 Book 类;每次调用 Book(...) 都建立一条新的书籍记录。
class Book:
def __init__(self, title):
self.title = title
self.finished = False
def finish(self):
self.finished = True
first = Book("Python")
second = Book("NumPy")
first.finish()
print(first.title, first.finished)
print(second.title, second.finished)得到 Python True 与 NumPy False。Book 是类,说明这类记录怎样初始化、提供哪些操作;first 和 second 指向两个 Book 实例。first.title、first.finished 是属性访问,类中定义的 finish 通过实例使用时成为方法。
可以把原先的 finish_book(first) 与现在的 first.finish() 对照:前者把对象作为普通参数写出来,后者把对象放在点号前面。Python 会把这个对象安排到方法的第一个参数 self,修改对象的规则仍然与上一章一致。
2. 创建对象与 __init__ 初始化
执行 Book("Python") 时,类的调用过程先取得新实例,再用它调用 __init__。本例可以按下面的动作阅读:
- 建立一个 Book 实例,暂时记作 B1。
- 调用初始化方法,把 B1 交给
self,把"Python"交给title。 self.title = title在 B1 上保存书名,self.finished = False保存初始状态。- 初始化结束,类调用交回 B1,外面的
first再绑定到它。
__init__ 是初始化方法,不是负责分配实例的那一步;创建实例涉及的 __new__ 通常由已有实现完成。__init__ 初始化现有的 self,正常结束返回 None;调用 Book(...) 得到的实例由类的调用过程交回,不需要在 __init__ 中 return self。
类名采用 BookShelf 这样的首字母大写形式,属性与方法继续使用 finished、add_book 这样的写法。类本身也是对象,可以绑定到其他名称;例如 record_type = Book 后,record_type("Python") 同样创建 Book 实例。类与实例