You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保函数输入为指定选项?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")

关键优化点

  1. 类型安全限制:通过request_type: RequestType的类型注解,静态检查工具(如mypy)会在编码阶段就拦截非枚举成员的传入,从源头避免非法输入。
  2. 枚举逻辑正确:每个请求类型都是独立的枚举成员,清晰对应HTTP方法,不会出现原代码中枚举对象和字符串不匹配的问题。
  3. 简化请求映射:通过枚举方法直接获取对应的requests函数,替代冗余的if-elif判断,代码更简洁易维护。
  4. 完善错误处理:同时覆盖非法请求类型和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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 11:02:02