2.20. 类入门

把数据以及作用于这些数据的函数归并到单一名称之下。当若干个状态属于同一整体,且脚本中大多数函数都以这同一组值作为参数时,使用类就很值得。

2.20.1. class 关键字

关键字是 class。其类体包含一个 __init__ 方法,每次创建新实例时都会运行:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point(3, 4)
print(p.x, p.y)

输出::

3 4

Point 是类;p 是它的一个实例。调用 Point(3, 4) 时的括号会调用 __init__,后者将参数赋给新实例的属性。self 是实例的惯用名称;self.x 设置一个属性,实例的其余方法将读取它。

2.20.2. 何时使用类

当下列条件同时成立时,请使用类:

  • 若干个相关的值始终一起出现(一个点的 xy;一次传感器读数的值、单位和时间戳)。

  • 有几个函数接收这同一组值并对它们进行操作。

  • 需要同时让多个这样的数据束存活并彼此区分,这很有用。

如果数据是一次性的,普通的 dicttuple 通常就足够了。如果你只需要一束常量,模块级变量就可以。类并不是默认的容器——只有当状态与行为想要紧密结合在一起时,类才有用武之地。

2.20.3. __init__ 做什么

__init__ 只是一个普通方法。在其中赋给 self 的任何东西都会成为新实例上的一个属性:

class Sensor:
    def __init__(self, name, unit):
        self.name = name
        self.unit = unit
        self.readings = []

temp = Sensor("temperature", "C")
print(temp.name, temp.unit, temp.readings)

输出::

temperature C []

readings 被初始化为一个空列表——每个新实例都得到属于自己的列表,而非共享的列表。任何未赋给 self 的东西都只是 __init__ 的局部变量,在它返回时就消失了。