如何确保函数输入为指定选项?HTTP请求包装器请求类型校验
如何确保HTTP请求包装器的请求类型为合法输入?
我想给requests库的包装器定义类似枚举的合法请求类型列表(支持GET、PUT、DELETE等),用来处理HTTP请求并做错误处理,请问怎么保证传入的请求类型是合法的?
我的尝试代码及输出
输出结果:
request type: request_type_library.request_type Uknown request type. Defaulted to get. Valid Request types: {<request_type_library.request_type: 1>: ['GET', 'PUT', 'DELETE']}
代码:
import requests from enum import Enum, auto class RequestTypeLibrary(Enum): request_type = auto() request_type_dictionary = {RequestTypeLibrary.request_type: ["GET","PUT","DELETE"]} class RequestTypeLoader: def __init__(self, request_type: RequestTypeLibrary): self.request_type = request_type def load_request_type(self): print(f"loaded request type: {request_type_dictionary[self.request_type]}") def request_wrapper(request_type: RequestTypeLibrary,url,timeout=10): print("request type:", request_type) if request_type=="GET": r= requests.get(url,timeout=timeout) elif request_type=="PUT": r= requests.put(url,timeout=timeout) elif request_type=="DELETE": r= requests.delete(url,timeout=timeout) else: r= requests.get(url,timeout=timeout) print("Uknown request type. Defaulted to get. Valid Request types: ", request_type_dictionary) return r r = request_wrapper(request_type=RequestTypeLibrary.request_type,url=url,timeout=10,)
正确实现方式
你的代码核心问题在于枚举定义逻辑错误:你把所有请求类型塞进了一个枚举成员的对应列表里,而且后续直接拿枚举对象和字符串(比如"GET")做比较,自然永远不匹配,导致触发默认分支。
正确的做法是把每个合法请求类型直接定义为独立的枚举成员,结合类型注解从源头限制输入合法性,同时让枚举和requests的请求方法做映射,简化代码逻辑:
改进后的完整代码
import requests from enum import Enum # 将每个合法请求类型定义为枚举成员,值可以对应请求方法或字符串 class RequestType(Enum): GET = "GET" PUT = "PUT" DELETE = "DELETE" # 给枚举添加方法,返回对应的requests请求函数 def get_request_func(self): func_map = { RequestType.GET: requests.get, RequestType.PUT: requests.put, RequestType.DELETE: requests.delete } return func_map[self] def request_wrapper(request_type: RequestType, url, timeout=10): try: # 通过枚举直接获取请求函数 request_func = request_type.get_request_func() response = request_func(url, timeout=timeout) response.raise_for_status() # 主动抛出HTTP状态码错误(4xx/5xx) return response except ValueError: # 捕获非法枚举值(比如强制传入不在枚举内的字符串) valid_types = [rt.value for rt in RequestType] print(f"非法请求类型,请传入以下合法类型:{valid_types}") # 可选:返回默认GET请求或抛出异常 return requests.get(url, timeout=timeout) except requests.exceptions.RequestException as e: # 处理requests库的各类请求异常(超时、连接失败等) print(f"请求执行失败:{str(e)}") raise # 也可以根据业务需求返回自定义错误结果 # 使用示例 # 传入合法枚举成员 response = request_wrapper(RequestType.GET, "https://example.com") # 若传入非法值(如RequestType("POST")),会触发错误处理 # response = request_wrapper(RequestType("POST"), "https://example.com")
关键优化点
- 类型安全限制:通过
request_type: RequestType的类型注解,静态检查工具(如mypy)会在编码阶段就拦截非枚举成员的传入,从源头避免非法输入。 - 枚举逻辑正确:每个请求类型都是独立的枚举成员,清晰对应HTTP方法,不会出现原代码中枚举对象和字符串不匹配的问题。
- 简化请求映射:通过枚举方法直接获取对应的requests函数,替代冗余的if-elif判断,代码更简洁易维护。
- 完善错误处理:同时覆盖非法请求类型和HTTP请求异常两种场景,提升代码鲁棒性。
如果追求极简实现,也可以直接把枚举值设为requests的请求函数:
import requests from enum import Enum class RequestType(Enum): GET = requests.get PUT = requests.put DELETE = requests.delete def request_wrapper(request_type: RequestType, url, timeout=10): return request_type.value(url, timeout=timeout) # 使用示例 response = request_wrapper(RequestType.GET, "https://example.com")
内容的提问来源于stack exchange,提问作者tbickford
相关产品推荐
相关产品推荐

