161 lines
5.3 KiB
Python
161 lines
5.3 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""
|
||
Day_2 参考解答
|
||
=============
|
||
今天的题目只用基础语法,但每个都是后端开发的真实场景。
|
||
建议:先自己写,写不出来再看;看完后把代码关掉,自己再默写一遍。
|
||
"""
|
||
|
||
import time
|
||
|
||
# ============================================================
|
||
# 题目一:解析 URL 查询参数
|
||
# ============================================================
|
||
|
||
def parse_query_string(query):
|
||
"""把 'username=zhangsan&age=20' 解析成 {'username': 'zhangsan', 'age': '20'}"""
|
||
result = {}
|
||
if not query: # 边界 1:空输入
|
||
return result
|
||
for item in query.split('&'): # 先按 & 切成若干段
|
||
if '=' in item:
|
||
key, value = item.split('=', 1) # maxsplit=1:值里可能也含有 '=',只切第一个
|
||
else:
|
||
key, value = item, '' # 边界 3:没有 = 的参数,值记为空字符串
|
||
result[key] = value # 字典赋值天然处理"重复键覆盖"和"值为空"
|
||
return result
|
||
|
||
|
||
# 进阶:URL 编码还原(把 + 和 %20 还原成空格)
|
||
def url_decode(value):
|
||
return value.replace('+', ' ').replace('%20', ' ')
|
||
|
||
|
||
def parse_query_string_advanced(query):
|
||
result = {}
|
||
if not query:
|
||
return result
|
||
for item in query.split('&'):
|
||
if '=' in item:
|
||
key, value = item.split('=', 1)
|
||
else:
|
||
key, value = item, ''
|
||
result[key] = url_decode(value)
|
||
return result
|
||
|
||
|
||
# 一个小测试
|
||
if __name__ == '__main__':
|
||
print(parse_query_string('username=zhangsan&age=20&city=qingdao'))
|
||
# {'username': 'zhangsan', 'age': '20', 'city': 'qingdao'}
|
||
print(parse_query_string('name=a&name=b&flag'))
|
||
# {'name': 'b', 'flag': ''}
|
||
print(parse_query_string(''))
|
||
# {}
|
||
print(parse_query_string_advanced('name=Zhang+San&city=A%20B'))
|
||
# {'name': 'Zhang San', 'city': 'A B'}
|
||
|
||
|
||
# ============================================================
|
||
# 题目二:万能日志记录器
|
||
# ============================================================
|
||
|
||
def log_call(func, label=""):
|
||
"""给函数包一层日志。func 被调用时打印参数和耗时。"""
|
||
def wrapper(*args, **kwargs):
|
||
tag = f"[{label}] " if label else ""
|
||
print(f"{tag}[LOG] 调用函数 {func.__name__},参数为 args={args}, kwargs={kwargs}")
|
||
start = time.time()
|
||
result = func(*args, **kwargs) # 原样透传参数
|
||
elapsed = time.time() - start
|
||
print(f"{tag}[LOG] {func.__name__} 执行完成,耗时 {elapsed:.4f} 秒")
|
||
return result # 原样返回结果
|
||
return wrapper
|
||
|
||
|
||
@log_call # 等价于 add = log_call(add)
|
||
def add(a, b):
|
||
return a + b
|
||
|
||
|
||
def multiply(a, b):
|
||
return a * b
|
||
|
||
multiply = log_call(multiply, label="核心计算") # 进阶:带标签
|
||
|
||
|
||
if __name__ == '__main__':
|
||
print(add(1, 2))
|
||
print(multiply(3, 4))
|
||
# 输出示例:
|
||
# [LOG] 调用函数 add,参数为 args=(1, 2), kwargs={}
|
||
# [LOG] add 执行完成,耗时 0.0000 秒
|
||
# 3
|
||
# [核心计算][LOG] 调用函数 multiply,参数为 args=(3, 4), kwargs={}
|
||
# [核心计算][LOG] multiply 执行完成,耗时 0.0000 秒
|
||
# 12
|
||
|
||
|
||
# ============================================================
|
||
# 题目三:模拟注册接口的参数校验
|
||
# ============================================================
|
||
|
||
class ValidationError(Exception):
|
||
"""自定义校验异常:参数不合法时抛出"""
|
||
pass
|
||
|
||
|
||
def validate_registration(data):
|
||
username = data.get("username")
|
||
email = data.get("email")
|
||
age = data.get("age")
|
||
|
||
if not username or len(username) < 3:
|
||
raise ValidationError("用户名必须存在且长度不少于 3")
|
||
if not email or "@" not in email or "." not in email:
|
||
raise ValidationError("邮箱必须包含 @ 和 .")
|
||
if age is None:
|
||
raise ValidationError("年龄必须存在")
|
||
try:
|
||
age_int = int(age) # 字符串 "20" 也能转
|
||
except (TypeError, ValueError):
|
||
raise ValidationError("年龄必须是整数")
|
||
if not (1 <= age_int <= 120):
|
||
raise ValidationError("年龄必须在 1~120 之间")
|
||
|
||
|
||
def register():
|
||
data = {"username": "zhangsan", "email": "zs@163.com", "age": "20"}
|
||
try:
|
||
validate_registration(data)
|
||
print(f"注册成功,欢迎 {data['username']}!")
|
||
except ValidationError as e:
|
||
print(f"校验失败: {e}")
|
||
|
||
|
||
# ---- 进阶:把规则做成数据 ----
|
||
def is_valid_email(email):
|
||
return isinstance(email, str) and "@" in email and "." in email
|
||
|
||
|
||
def validate(data, rules):
|
||
"""rules: {字段名: (校验函数, 错误信息)},返回所有错误列表"""
|
||
errors = []
|
||
for field, (check, message) in rules.items():
|
||
if not check(data.get(field)):
|
||
errors.append(f"{field}: {message}")
|
||
return errors
|
||
|
||
|
||
RULES = {
|
||
"username": (lambda v: isinstance(v, str) and len(v) >= 3, "用户名长度不足 3"),
|
||
"email": (is_valid_email, "邮箱格式不正确"),
|
||
"age": (lambda v: isinstance(v, int) and 1 <= v <= 120, "年龄非法"),
|
||
}
|
||
|
||
|
||
if __name__ == '__main__':
|
||
register() # 注册成功,欢迎 zhangsan!
|
||
print(validate({"username": "zs", "email": "bad", "age": 200}, RULES))
|
||
# ['username: 用户名长度不足 3', 'email: 邮箱格式不正确', 'age: 年龄非法']
|