# -*- 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: 年龄非法']