简单例子说明 python 类的创建语法
class Report:
def __init__(self):
self.rows = []
def add(self, name, passed, detail=""):
self.rows.append((name, passed, detail))
mark = "PASS" if passed else ("FAIL" if passed is False else "SKIP")
print(f" [{mark}] {name}" + (f" — {detail}" if detail else ""))
def summary(self):
p = sum(1 for _, ok, _ in self.rows if ok is True)
f = sum(1 for _, ok, _ in self.rows if ok is False)
s = sum(1 for _, ok, _ in self.rows if ok is None)
return p, f, s
这段代码虽然简短,却是一个极佳的 Python 类语法教学样本。它没有使用任何高级特性(如 dataclass、property 或继承),而是展示了最纯粹、最基础的 Python 面向对象构建范式。
以下是对其包含的类创建语法的逐层解读:
1. 类的声明与命名规范
class Report:
class关键字:定义一个新类型。- PascalCase 命名:Python 约定类名使用大驼峰(
Report而非report或my_report),以区别于函数和变量。 - 隐式继承
object:在 Python 3 中,class Report:等价于class Report(object):。即使不显式写出,它也自动继承自object,获得所有基础对象协议(如__str__、__repr__等)。
2. 构造器与实例状态初始化
def __init__(self):
self.rows = []
这是 Python 类中最核心的语法模式,包含三个关键概念:
| 语法元素 | 含义 | 常见误区 |
|---|---|---|
__init__ |
初始化方法,非构造函数 | 真正的构造是 __new__;__init__ 只负责初始化已创建的对象 |
self |
实例自身的引用(显式传递) | 不同于 Java/C++ 的隐式 this,Python 要求第一个参数必须是 self |
self.rows = [] |
动态绑定实例属性 | Python 无需提前声明字段;属性在赋值时创建,且绑定到具体实例 |
⚠️ 关键设计细节:可变默认值陷阱的规避
这里将self.rows = []放在__init__内部而非作为类变量,是绝对正确的做法。如果写成rows = []作为类变量,所有Report实例将共享同一个列表——这是 Python 初学者最常踩的坑。此代码完美避开了这一点。
3. 实例方法与封装
def add(self, name, passed, detail=""):
self作为第一参数:所有实例方法必须显式接收self,调用时由解释器自动传入,无需手动写report.add(report, ...)。- 默认参数
detail="":展示了方法签名的灵活性。注意这里使用的是不可变默认值(空字符串),安全无副作用。 - 数据封装:外部通过
add()操作数据,而非直接report.rows.append(...)。虽然 Python 不强制私有化,但这种模式为未来添加验证、日志或格式变更预留了扩展点。
4. 三元表达式与链式条件
mark = "PASS" if passed else ("FAIL" if passed is False else "SKIP")
这行代码展示了 Python 条件表达式的嵌套能力,同时体现了身份比较 vs 值比较的精确区分:
is True/is False/is None:使用is进行身份比较,而非==。这是处理三态布尔(True/False/None)的最佳实践,因为==可能被自定义__eq__重载,而is永远检查内存地址。- 嵌套三元:
A if cond1 else (B if cond2 else C)是 Python 中表达多分支赋值的惯用方式,比多层if-elif-else更紧凑。
5. 生成器表达式与聚合计算
p = sum(1 for _, ok, _ in self.rows if ok is True)
summary() 方法浓缩了多个 Python 高级语法:
- 生成器表达式:
(1 for ...)而非[1 for ...]。传给sum()时不会创建中间列表,内存复杂度 O(1)。 - 元组解包:
_, ok, _直接在循环头解包三元组,_表示“有意忽略”的字段,是 Python 社区的强约定。 - 过滤式聚合:
sum(... if condition)将计数与过滤合为一体,比先filter再len更高效且更具可读性。 - 严格身份检查:再次使用
is True/is False/is None,确保不会被"non-empty string"或0等 truthy/falsy 值误判。
📌 总结:这段代码体现的 Python 类设计哲学
这段代码虽简单,却完整展现了 Python OOP 的核心原则:
- 显式优于隐式:
self显式传递,属性显式绑定,没有魔法般的自动注入。 - 约定优于强制:用
_表示忽略,用 PascalCase 区分类名,用is区分三态——全靠社区约定而非编译器强制。 - 简洁但不简陋:7 行
summary()完成了统计、解包、过滤、聚合四件事,且零中间内存分配。 - 防御性编程内化于语法:可变默认值放
__init__、三态判断用is、数据通过方法访问——这些不是额外检查,而是语法层面的自然选择。
如果你要在此基础上演进,下一步可以考虑用 @dataclass 替代手写 __init__,或用 Enum 替代字符串标记,但当前版本作为理解 Python 类机制的最小完备样本,已经无可挑剔。

浙公网安备 33010602011771号