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

如何不创建新对象转换Python对象属性类型适配Requests请求头校验?

问题背景

Python的requests库从2.28.0版本开始引入了HTTP请求头的严格类型检查,若使用Enum实例作为请求头字典的键,会抛出InvalidHeader异常:

requests.exceptions.InvalidHeader: Header part (<HttpHeaders.content_encoding: 'X-Content-Encoding'>) from {<HttpHeaders.content_encoding: 'X-Content-Encoding'>: 'gzip'} must be of type str or bytes, not <enum 'HttpHeaders'>

原有的修复方案是通过字典推导式生成新字典,将Enum键转换为对应的字符串值:

myheaders= {xkey.value: xval for xkey, xval in myheaders.items() }

但该方案会创建新的字典实例,虽在小字典场景下影响极小,但并非理想方案。

推荐修复方案

方案一:从源头避免使用Enum实例作为键

直接在初始化字典时使用Enum的value属性,让字典的键从一开始就是字符串类型,无需后续转换,完全避免额外对象创建:

import enum
import requests

class HttpHeaders(str, enum.Enum):
    forwarded_for = 'X-Forwarded-For'
    content_type = 'Content-Type'

myheaders = {
    HttpHeaders.forwarded_for.value: "192.168.0.1",
    HttpHeaders.content_type.value: "text/plain",
}

requests.post('http://127.0.0.1:8000', "zima", headers=myheaders)

方案二:自定义适配Enum键的字典类

如果必须保留Enum实例作为字典键的写法,可以自定义一个字典子类,重写遍历相关方法,动态返回Enum的value而无需创建新字典:

import enum
import requests

class EnumKeyDict(dict):
    def items(self):
        # 遍历键值对时,自动将Enum实例转为对应的字符串
        return ((k.value if isinstance(k, enum.Enum) else k, v) for k, v in super().items())
    
    def keys(self):
        # 返回键时自动转换Enum实例
        return (k.value if isinstance(k, enum.Enum) else k for k in super().keys())
    
    def __iter__(self):
        # 迭代字典时返回转换后的键
        return (k.value if isinstance(k, enum.Enum) else k for k in super().__iter__())

class HttpHeaders(str, enum.Enum):
    forwarded_for = 'X-Forwarded-For'
    content_type = 'Content-Type'

myheaders = EnumKeyDict({
    HttpHeaders.forwarded_for: "192.168.0.1",
    HttpHeaders.content_type: "text/plain",
})

requests.post('http://127.0.0.1:8000', "zima", headers=myheaders)

该方案通过动态转换替代预转换,不会创建新的字典实例,仅在requests遍历请求头时进行类型适配。


内容的提问来源于stack exchange,提问作者fakej Gazeta.pl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:55:19