零基础入门python04:用注册校验理解字典、集合和条件判断
一、上一篇课后练习讲解
上一篇的练习是按编号删除购物清单商品。关键是先把用户输入的编号从字符串转成整数,再检查 1 <= index <= len(items),最后使用 pop(index - 1) 删除。不能直接相信输入,否则会出现 IndexError。
可执行验收答案
将删除逻辑独立成函数,调用者可以是命令行,也可以是后续的 Web 接口:
python
def remove_item(items: list[dict], raw_index: str) -> dict:
try:
index = int(raw_index)
except ValueError as exc:
raise ValueError("编号必须是整数") from exc
if not 1 <= index <= len(items):
raise IndexError(f"编号范围是 1~{len(items)}")
return items.pop(index - 1)
cart = [{"name": "牛奶", "quantity": 2}, {"name": "面包", "quantity": 1}]
assert remove_item(cart, "2")["name"] == "面包"
for bad in ("abc", "0", "9"):
try:
remove_item(cart, bad)
except (ValueError, IndexError) as exc:
print(bad, type(exc).__name__, exc)
else:
raise AssertionError("非法编号没有失败")
print("remaining:", cart)
预期只剩牛奶;abc 是类型错误,0/9 是范围错误。交互层捕获异常后打印提示,业务函数不要直接 input 或 print,这样测试才可以传入不同字符串。
二、本篇要完成什么
做一个注册信息校验器:检查用户名是否为空、年龄是否合理、密码长度是否达标,以及兴趣标签是否有重复。字典保存一份用户资料,集合负责去重,条件判断负责表达业务规则。

三、字典和集合的选择
python
user = {'name': '小李', 'age': 20, 'roles': {'reader'}}
allowed_roles = {'reader', 'author'}
print(user['name'])
print(user['roles'] <= allowed_roles)
字典适合按字段名读取资料;集合适合判断成员关系和去重。roles <= allowed_roles 表示用户申请的所有角色都必须属于系统允许的角色集合。
四、完整实现
python
def validate_registration(name: str, age: int, password: str, tags: list[str]) -> tuple[bool, str]:
"""集中保存注册规则,返回是否通过和给用户看的原因。"""
if not name.strip():
return False, '用户名不能为空'
if age < 14 or age > 120:
return False, '年龄必须在14到120之间'
if len(password) < 8:
return False, '密码至少需要8位'
clean_tags = {tag.strip().lower() for tag in tags if tag.strip()}
if len(clean_tags) == 0:
return False, '至少选择一个兴趣标签'
return True, f'校验通过,标签数量:{len(clean_tags)}'
def main() -> None:
raw_tags = input('兴趣标签(逗号分隔):').split(',')
try:
age = int(input('年龄:'))
except ValueError:
print('年龄必须是整数')
return
ok, message = validate_registration(
input('用户名:'), age, input('密码:'), raw_tags
)
print('注册成功' if ok else '注册失败', message)
if __name__ == '__main__':
main()
集合推导式同时完成清理、统一大小写和去重。规则函数没有直接 print,这样命令行、Flask 和 FastAPI 都可以复用。
五、运行结果与边界
text
兴趣标签(逗号分隔):Python, python, 后端
年龄:22
用户名:alice
密码:python123
注册成功 校验通过,标签数量:2
输入空密码时返回"密码至少需要8位";输入 abc 作为年龄时在转换阶段返回"年龄必须是整数"。
六、验收和练习
验证空用户名、未成年年龄、短密码、重复标签和正常注册五种情况。课后练习:增加 email 格式校验,并说明正则表达式校验应该放在命令行层还是业务函数层。下一篇把循环和推导式用于成绩统计。
实战补充:注册校验的错误清单
注册校验不是写几个 if 就结束。业务需要同时检查邮箱格式、密码长度、两次密码一致和用户名是否重复;每一项失败都应该告诉用户如何修改。
python
def validate_registration(data: dict, used_names: set[str]) -> list[str]:
errors = []
username = data.get('username', '').strip()
password = data.get('password', '')
repeat = data.get('repeat_password', '')
if len(username) < 3:
errors.append('用户名至少 3 个字符')
if username.casefold() in {name.casefold() for name in used_names}:
errors.append('用户名已经存在')
if len(password) < 8:
errors.append('密码至少 8 个字符')
if password != repeat:
errors.append('两次密码不一致')
return errors
集合适合做"是否已经出现过"的快速判断,但集合本身不保存顺序;需要展示错误时使用列表。数据库真正注册时仍要有 UNIQUE 约束,内存集合只能改善提示。
运行结果与课后练习
分别测试空字段、重复用户名、短密码和成功输入;记录错误列表和最终状态。课后增加邮箱格式校验和密码强度提示,下一篇用循环处理多名学生的成绩。
本篇结束:完整模块文件
本节不是代码片段,而是本篇结束时该模块的完整版本。请先备份旧文件,再整体替换;替换后重新运行本篇命令和测试。阅读时重点看本篇新增的函数、事务边界和错误处理,未涉及的代码先不要自行删减。
main.py
python
user={'name':input('昵称:').strip(),'age':int(input('年龄:')),'tags':{'python','backend'}}
if not user['name']: print('昵称不能为空')
elif user['age']<14: print('暂不接受14岁以下用户注册')
else: print('注册信息有效',user)