← 返回 Day 32 正文

Day 32 · 练习与清单

Day 032 — 属性与方法:完成清单与练习题

✅ 完成清单

概念理解

Python 实现

代码实践


📝 练习题

练习 1:实现 Temperature 类

python
"""
实现 Temperature 类,支持摄氏度和华氏度互相转换。
要求使用 property 实现自动转换。

属性:
  celsius: 摄氏度 (getter/setter)
  fahrenheit: 华氏度 (只读, 自动计算)

方法:
  @classmethod from_kelvin(k): 从开尔文创建
  @staticmethod to_absolute_zero(): 返回绝对零度值
"""
class Temperature:
    # 你的代码
    pass

# 测试
t = Temperature(25)
print(t.celsius)      # → 25
print(t.fahrenheit)   # → 77.0
t.celsius = 0
print(t.fahrenheit)   # → 32.0

t2 = Temperature.from_kelvin(300)
print(t2.celsius)     # → 26.85

练习 2:实现 ShoppingCart 类

python
"""
实现购物车类 ShoppingCart,包含:

类属性:
  tax_rate: 税率 (0.08)
  free_shipping_threshold: 免运费门槛 ($50)

实例属性:
  items: list of (name, price, quantity)

实例方法:
  add_item(name, price, quantity=1)
  remove_item(name)
  update_quantity(name, quantity)

计算属性 (@property):
  subtotal: 小计
  tax: 税费
  total: 总价 (含税)
  item_count: 商品总数
  qualifies_free_shipping: 是否免运费

类方法:
  @classmethod from_cart(other): 复制购物车
  @classmethod update_tax_rate(new_rate): 更新税率

静态方法:
  @staticmethod format_price(price): 格式化价格
"""
class ShoppingCart:
    tax_rate = 0.08
    free_shipping_threshold = 50.0

    # 你的代码
    pass

# 测试
cart = ShoppingCart()
cart.add_item("Python编程", 39.99, 2)
cart.add_item("鼠标", 25.00, 1)
print(f"小计: ${cart.subtotal:.2f}")
print(f"总价: ${cart.total:.2f}")
print(f"免运费: {cart.qualifies_free_shipping}")

练习 3:实现 User 类(带验证)

python
"""
实现 User 类,使用 property 进行数据验证。

属性:
  username: 3-20个字符,只能包含字母数字和下划线
  email: 必须包含 @ 和 .
  password: 至少8个字符,必须包含大小写字母和数字
  is_admin: 只读,默认为 False
  login_attempts: 只读,默认为 0

方法:
  login(password): 验证密码
  is_valid_email(email): 静态方法,验证邮箱格式
  generate_temp_password(): 类方法,生成临时密码
"""
import re

class User:
    # 你的代码
    pass

# 测试
user = User("alice_wonder", "alice@example.com", "SecurePass1")
print(user.username)   # → alice_wonder
print(user.email)      # → alice@example.com

try:
    User("ab", "test@test.com", "Pass1234")  # username 太短
except ValueError as e:
    print(f"验证通过: {e}")

练习 4:实现 TodoList 类

python
"""
实现待办事项列表 TodoList,使用 property 管理统计信息。

类属性:
  priority_levels: {1: "高", 2: "中", 3: "低"}

TodoItem: (title, completed=False, priority=2)

实例方法:
  add(title, priority=2)
  complete(index)
  uncomplete(index)
  remove(index)
  sort_by_priority()
  filter(completed=None, priority=None)

计算属性:
  total: 总数
  completed_count: 已完成数
  pending_count: 待完成数
  completion_rate: 完成率 (百分比)
  top_priority: 最高优先级的未完成任务列表
"""
class TodoList:
    priority_levels = {1: "高", 2: "中", 3: "低"}

    # 你的代码
    pass

# 测试
todo = TodoList()
todo.add("学习Python", 1)
todo.add("买菜", 3)
todo.add("写报告", 1)
print(f"总任务: {todo.total}")           # → 3
print(f"完成率: {todo.completion_rate}%")  # → 0.0%
todo.complete(0)
print(f"完成率: {todo.completion_rate}%")  # → 33.3%

练习 5:实现 Time 类(描述符)

python
"""
实现时间描述符 TimeDescriptor,自动将超过60的值进位。

例如: 设置 seconds=120 → 自动变为 2 minutes
     设置 minutes=90  → 自动变为 1 hour 30 minutes

用于 Time 类的 hours, minutes, seconds 属性。
"""
class TimeDescriptor:
    """时间描述符 — 自动进位"""

    def __init__(self, field, max_value, carry_to=None):
        """
        field: 字段名 (用于存储)
        max_value: 最大值 (超过则进位)
        carry_to: 进位到的字段名
        """
        # 你的代码
        pass

    def __get__(self, obj, objtype=None):
        pass

    def __set__(self, obj, value):
        pass


class Time:
    """时间类 — 使用描述符自动进位"""
    seconds = TimeDescriptor('_seconds', 60, 'minutes')
    minutes = TimeDescriptor('_minutes', 60, 'hours')
    hours = TimeDescriptor('_hours', 24, None)

    def __init__(self, hours=0, minutes=0, seconds=0):
        self.hours = hours
        self.minutes = minutes
        self.seconds = seconds

    def __str__(self):
        return f"{self.hours:02d}:{self.minutes:02d}:{self.seconds:02d}"


# 测试
t = Time(0, 0, 150)  # 150秒 → 2分30秒
print(t)  # → 00:02:30

t.minutes = 90  # 90分 → 1时30分
print(t)  # → 01:30:30

📊 自评表

技能 初学者 理解 掌握 熟练
实例属性 vs 类属性 ☐ ☐ ☐ ☐
@classmethod ☐ ☐ ☐ ☐
@staticmethod ☐ ☐ ☐ ☐
@property getter/setter ☐ ☐ ☐ ☐
计算属性 ☐ ☐ ☐ ☐
@cached_property ☐ ☐ ☐ ☐
描述符协议 ☐ ☐ ☐ ☐
getattr / setattr ☐ ☐ ☐ ☐

🔗 参考资源