Python 自定义容器类

部署运行你感兴趣的模型镜像

总结:自定义容器类的核心优势

场景自定义People普通列表

代码复用

✅ 方法一次定义,处处调用

❌ 逻辑重复,到处写

业务规则集中

✅ 添加、查找、过滤等规则封装在类内

❌ 规则散落在业务代码中

变更维护成本

✅ 修改只需改类内部

❌ 需全局搜索替换

团队协作

✅ 接口清晰,不易误用

❌ 依赖文档或口头约定

测试友好

✅ 可对People单独单元测试

❌ 逻辑耦合在流程中,难测试

import json
from typing import List, Optional, Generator


class Person:
    def __init__(self, name: str, age: int):
        if not isinstance(name, str) or not name.strip():
            raise ValueError("姓名必须是非空字符串")
        if not isinstance(age, int) or age < 0:
            raise ValueError("年龄必须是非负整数")
        self.name = name.strip()
        self.age = age

    def __repr__(self):
        return f"Person(name='{self.name}', age={self.age})"

    def to_dict(self):
        """将 Person 转为字典,便于序列化"""
        return {"name": self.name, "age": self.age}


class People:
    def __init__(self, allow_duplicates: bool = True):
        """
        初始化人群容器。
        :param allow_duplicates: 是否允许同名人员(默认允许)
        """
        self._persons: List[Person] = []
        self._allow_duplicates = allow_duplicates

    def add(self, person: Person) -> None:
        """
        添加一个 Person 实例。
        如果不允许重复姓名且已存在同名人员,则抛出 ValueError。
        """
        if not isinstance(person, Person):
            raise TypeError("只能添加 Person 类型的实例")
        
        if not self._allow_duplicates:
            if self.find_by_name(person.name) is not None:
                raise ValueError(f"已存在名为 '{person.name}' 的人员,不允许重复添加。")
        
        self._persons.append(person)

    def find_by_name(self, name: str) -> Optional[Person]:
        """返回第一个匹配姓名的 Person,未找到返回 None"""
        name = name.strip()
        for p in self._persons:
            if p.name == name:
                return p
        return None

    def adults(self) -> Generator[Person, None, None]:
        """返回一个生成器,仅包含年龄 >=18 的 Person"""
        return (p for p in self._persons if p.age >= 18)

    def average_age(self) -> float:
        """计算平均年龄,若无人则返回 0.0"""
        if not self._persons:
            return 0.0
        return sum(p.age for p in self._persons) / len(self._persons)

    def to_json(self, indent: int = 2) -> str:
        """将所有人员转换为 JSON 字符串"""
        data = [p.to_dict() for p in self._persons]
        return json.dumps(data, ensure_ascii=False, indent=indent)

    def __iter__(self):
        """支持 for person in people"""
        return iter(self._persons)

    def __len__(self):
        """支持 len(people)"""
        return len(self._persons)

    def __repr__(self):
        """开发者友好的字符串表示"""
        return f"People({self._persons})"

    def __bool__(self):
        """支持 if people: 判断是否为空"""
        return len(self._persons) > 0


# ==================== 使用示例 ====================
if __name__ == "__main__":
    # 创建人群(不允许同名)
    people = People(allow_duplicates=False)

    # 添加人员
    people.add(Person("Alice", 30))
    people.add(Person("Bob", 17))
    people.add(Person("Charlie", 25))

    # 尝试重复添加(会报错)
    try:
        people.add(Person("Alice", 28))
    except ValueError as e:
        print("❌ 添加失败:", e)

    # 遍历所有人
    print("👥 所有人员:")
    for p in people:
        print(p)

    # 查找某人
    alice = people.find_by_name("Alice")
    print(f"\n🔍 找到 Alice: {alice}")

    # 遍历成年人
    print("\n🧑 成年人:")
    for adult in people.adults():
        print(adult)

    # 平均年龄
    print(f"\n📊 平均年龄: {people.average_age():.1f} 岁")

    # 转 JSON
    print("\n📄 JSON 输出:")
    print(people.to_json())

    # 其他功能
    print(f"\n🔢 总人数: {len(people)}")
    print(f"✅ 人群非空: {bool(people)}")

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值