Python 类与实例
把状态与操作放在一起
类定义一类对象的行为,实例保存各自状态。只有需要把相关状态与操作组合时才引入类;单纯计算通常函数即可。
python
class Notebook:
category = "notes" # 类属性,默认由各实例共享读取
def __init__(self, owner):
self.owner = owner
self.pages = [] # 每次构造都得到自己的列表
def add(self, text):
self.pages.append(text)
@classmethod
def from_owner(cls, owner):
return cls(owner)
@staticmethod
def valid_text(text):
return bool(text.strip())
a = Notebook("Alice")
b = Notebook.from_owner("Bob")
a.add("first")
assert a.pages == ["first"]
assert b.pages == []
assert Notebook.valid_text("hello")如果把 pages = [] 写在类体中,多个实例会共享同一个列表,除非显式覆盖。这是类属性和实例属性最容易混淆的地方。Python 属性也可从外部访问,self.owner 并不天然私有。
方法如何选择
| 写法 | 隐式传入 | 适用情况 |
|---|---|---|
| 实例方法 | 实例 self | 读写实例状态 |
@classmethod | 类 cls | 替代构造方式、需要感知子类的类级操作 |
@staticmethod | 无 | 与类相关,但不需要实例或类;也可以考虑模块函数 |
__init__ 初始化已创建的实例。继承可以重用并覆盖行为;调用父类实现用 super()。不要仅为了共享几行代码就建立复杂继承层级。
用类组织标准库测试
学会类与实例后,可以将独立测试组织为 unittest.TestCase 的子类。测试方法以 test_ 开头,assertEqual 用于检查实际值与预期值;测试运行器会发现并运行这些方法。
python
# test_total.py
import unittest
class TotalTest(unittest.TestCase):
def test_sum(self):
self.assertEqual(sum([1, 2, 3]), 6)shell
python -m unittest test_total先按 开发环境选择解释器,再运行上面的命令。示例使用标准库,不需要安装第三方测试工具。
练习与资料
为 Notebook.add 增加空文本检查,用两个实例验证修改互不影响。再比较把 pages 放在类体与 __init__ 中的行为。参见 类教程。下一步读 标准库。
参考解答
将Notebook中add方法替换为以下实现即可,其他方法保留;空白文本明确按ValueError拒绝:
python
def add(self, text):
if not self.valid_text(text):
raise ValueError("text must not be blank")
self.pages.append(text)提示:先验证再append。两个新实例中只给a添加一条时,b.pages应仍为空;给a传入空白应抛ValueError且a.pages不变。若把pages放进类体且实例没有同名属性,a和b会看到同一列表;这可用 a.pages is b.pages 核对。参考是替换方法片段,未执行。
继续阅读
- 开发实践
- 排错
- 开发实践