
本文首发于微信公众号「拙见python」,基础板块第 7 篇。
适合人群:已阅读第 2 篇:Python 面向对象编程并动手敲过代码的读者。
题目难度:⭐ → ⭐⭐⭐⭐⭐ 逐步提升,建议先自己写,再看答案。
做题须知
每道题标注了考察知识点和难度星级 先自己写,写不出来再看答案 答案不是唯一的,能跑通且逻辑正确就行 每道题答案下方附有思路解析
第 4 题:带校验的用户密码类 ⭐⭐⭐
考察知识点:封装(私有属性)、@property、@setter、异常处理
定义一个
User类:
初始化接收 username,密码默认为空字符串用 @property暴露password属性设置密码时校验:长度 6-20,必须包含数字和字母,否则抛出 ValueError提供 verify(password)方法验证密码是否正确密码不能被直接读取( @property返回"****")测试正常设置、非法密码、密码验证。
参考答案:
class User:def __init__(self, username):self.username = usernameself._password = ””# 私有属性,存储真实密码@propertydef password(self):”””读取密码时返回掩码,不暴露真实密码”””return ”****” if self._password else ”未设置”@password.setterdef password(self, value):”””设置密码时进行校验”””if not isinstance(value, str):raise ValueError(”密码必须是字符串”)if len(value) < 6 or len(value) > 20:raise ValueError(”密码长度必须在 6-20 个字符之间”)has_digit = any(c.isdigit() for c in value)has_alpha = any(c.isalpha() for c in value)if not (has_digit and has_alpha):raise ValueError(”密码必须同时包含数字和字母”)self._password = valueprint(f”✅ 密码设置成功”)def verify(self, password):”””验证密码是否正确”””return password == self._password# 测试user = User(”zhuojian_python”)print(user.password)# 未设置# 正常设置user.password = ”abc123456”print(user.password)# ****# 密码验证print(user.verify(”abc123456”))# Trueprint(user.verify(”wrong”))# False# 非法密码测试for bad_pwd in [”123”, ”onlyletters”, ”12345678”, ”a” * 25]:try:user.password = bad_pwdexcept ValueError as e:print(f”❌ 「{bad_pwd[:10]}」设置失败:{e}”)# ❌ 「123」设置失败:密码长度必须在 6-20 个字符之间# ❌ 「onlyletters」设置失败:密码必须同时包含数字和字母# ❌ 「12345678」设置失败:密码必须同时包含数字和字母# ❌ 「aaaaaaaaaa」设置失败:密码长度必须在 6-20 个字符之间
思路解析:
_password用单下划线表示受保护属性,外部不应直接访问。
@property 定义 password 的读取行为:返回 "****" 而非真实密码,这是封装的体现——外部能「读」但读不到原始值。
@password.setter 定义写入行为在赋值时自动触发校验逻辑。user.password = "abc123456" 实际调用的是 setter 方法。
any(c.isdigit() for c in value)用生成器表达式检查是否包含数字,比写循环更简洁。
真实密码存在 _password 中,但 @property 拦截了外部读取,实现了「可写不可读」的效果。
建议的练习方式:
先自己写——不看答案,能写多少写多少
卡住了回看文章——第 2 篇对应章节有完整示例
下一篇预告:Python 面向对象习题之5/10
夜雨聆风