Files
PythonLearn/03_面向对象/3_4_Python特殊方法与数据类/special_methods_dataclass_example.py

95 lines
3.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第 3-4 课完整示例Python 特殊方法与数据类
#
# 本示例对比普通类和 @dataclass并演示 __str__、自动 __repr__、
# 自动 __eq__、__post_init__ 以及 field(default_factory=list)。
from dataclasses import dataclass, field
class ManualProduct:
"""手动实现初始化、字符串显示和相等比较的普通类。"""
def __init__(self, name: str, price: float) -> None:
self.name = name
self.price = price
def __repr__(self) -> str:
"""返回适合开发和调试的对象表示。"""
return f"ManualProduct(name={self.name!r}, price={self.price!r})"
def __eq__(self, other: object) -> bool:
"""根据属性值判断两个商品是否相等。"""
if not isinstance(other, ManualProduct):
return NotImplemented
return self.name == other.name and self.price == other.price
@dataclass
class Product:
"""数据类会根据字段自动生成常用特殊方法。"""
name: str
price: float
def __post_init__(self) -> None:
"""在自动生成的 __init__ 执行后校验数据。"""
if self.price < 0:
raise ValueError("价格不能小于 0。")
def __str__(self) -> str:
"""返回面向使用者的友好文字。"""
return f"{self.name}{self.price}"
@dataclass
class Cart:
"""购物车使用工厂函数为每个实例创建独立列表。"""
owner: str
items: list[Product] = field(default_factory=list)
def add(self, product: Product) -> None:
"""向当前购物车添加商品。"""
self.items.append(product)
def main() -> None:
"""运行特殊方法与数据类示例。"""
manual_one = ManualProduct("机械键盘", 500.0)
manual_two = ManualProduct("机械键盘", 500.0)
print("差异 1普通类需要手动实现 Java 常见样板能力。")
print(repr(manual_one))
print(f"两个普通类对象按内容相等:{manual_one == manual_two}")
print()
keyboard_one = Product("机械键盘", 500.0)
keyboard_two = Product("机械键盘", 500.0)
print("差异 2@dataclass 自动生成 __init__、__repr__ 和 __eq__。")
print(repr(keyboard_one))
print(f"两个数据类对象按字段相等:{keyboard_one == keyboard_two}")
print()
print("差异 3__str__ 类似面向用户的 toString() 显示。")
print(str(keyboard_one))
print()
print("差异 4类型注解不会自动校验业务规则要在 __post_init__ 中实现。")
try:
Product("错误商品", -1.0)
except ValueError as error:
print(f"非法商品已被阻止:{error}")
print()
print("差异 5default_factory 确保不同购物车使用不同列表。")
first_cart = Cart("小明")
second_cart = Cart("小红")
first_cart.add(keyboard_one)
print(f"小明的商品数:{len(first_cart.items)}")
print(f"小红的商品数:{len(second_cart.items)}")
if __name__ == "__main__":
main()