简单例子说明 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 的核心原则:

  1. 显式优于隐式:self 显式传递,属性显式绑定,没有魔法般的自动注入。
  2. 约定优于强制:用 _ 表示忽略,用 PascalCase 区分类名,用 is 区分三态——全靠社区约定而非编译器强制。
  3. 简洁但不简陋:7 行 summary() 完成了统计、解包、过滤、聚合四件事,且零中间内存分配。
  4. 防御性编程内化于语法:可变默认值放 __init__、三态判断用 is、数据通过方法访问——这些不是额外检查,而是语法层面的自然选择。

如果你要在此基础上演进,下一步可以考虑用 @dataclass 替代手写 __init__,或用 Enum 替代字符串标记,但当前版本作为理解 Python 类机制的最小完备样本,已经无可挑剔。

posted @ 2026-10-01 17:54  立体风  阅读(5)  评论(0)    收藏  举报