Recientemente, estaba escribiendo una plataforma de prueba para la automatización de la interfaz. Encontré un pequeño problema en el paso de rellenar los datos del encabezado de respuesta en la interfaz de solicitud. Quiero usar el método (r.headers) que viene con la biblioteca de solicitudes para obtener el encabezado de respuesta, y luego obtenga el valor y páselo Para mostrarlo en la parte delantera, el efecto de visualización es el siguiente:
Todo estaba bien cuando comencé a depurar, pero para mantener un registro de estos datos, algo salió mal y se informó un error poco común:
La primera reacción es un problema relacionado con la serialización de django. Según el registro de errores, se puede rastrear hasta el error en el paso de crear almacenamiento de datos en lotes a través de ORM en el código. Después de analizarlo, todavía no hay ninguna pista:
Después de llegar al punto de interrupción, agregar comentarios y depurar, no encontré resultados y no sospeché que se debía a la adición de la operación de obtener el encabezado de respuesta.Después de que no tengo idea, no informaré un error después de comentar esta parte del código, ¡y puede ejecutarse normalmente!
Luego, después de un poco de depuración, descubrí que el encabezado de respuesta devuelto por las solicitudes es: <class 'requests.structures.CaseInsensitiveDict'>
este tipo, que es una estructura de datos personalizada para solicitudes, una estructura de datos que no distingue entre mayúsculas y minúsculas con claves de cadena puras, y también contiene algunos datos de bytes, por lo que en el secuencia Informará un error cuando se trata de una cadena json:
class CaseInsensitiveDict(MutableMapping):
"""A case-insensitive ``dict``-like object.
Implements all methods and operations of
``MutableMapping`` as well as dict's ``copy``. Also
provides ``lower_items``.
All keys are expected to be strings. The structure remembers the
case of the last key to be set, and ``iter(instance)``,
``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
will contain case-sensitive keys. However, querying and contains
testing is case insensitive::
cid = CaseInsensitiveDict()
cid['Accept'] = 'application/json'
cid['aCCEPT'] == 'application/json' # True
list(cid) == ['Accept'] # True
For example, ``headers['content-encoding']`` will return the
value of a ``'Content-Encoding'`` response header, regardless
of how the header name was originally stored.
If the constructor, ``.update``, or equality comparison
operations are given keys that have equal ``.lower()``s, the
behavior is undefined.
"""
def __init__(self, data=None, **kwargs):
self._store = OrderedDict()
if data is None:
data = {
}
self.update(data, **kwargs)
def __setitem__(self, key, value):
# Use the lowercased key for lookups, but store the actual
# key alongside the value.
self._store[key.lower()] = (key, value)
def __getitem__(self, key):
return self._store[key.lower()][1]
def __delitem__(self, key):
del self._store[key.lower()]
def __iter__(self):
return (casedkey for casedkey, mappedvalue in self._store.values())
def __len__(self):
return len(self._store)
def lower_items(self):
"""Like iteritems(), but with all lowercase keys."""
return (
(lowerkey, keyval[1])
for (lowerkey, keyval)
in self._store.items()
)
def __eq__(self, other):
if isinstance(other, Mapping):
other = CaseInsensitiveDict(other)
else:
return NotImplemented
# Compare insensitively
return dict(self.lower_items()) == dict(other.lower_items())
# Copy is required
def copy(self):
return CaseInsensitiveDict(self._store.values())
def __repr__(self):
return str(dict(self.items()))
Así que aquí lo convierto directamente a tipo de dictado para resolver el problema:
原:req_log['res_headers'] = r.headers
改:req_log['res_headers'] = dict(r.headers)
Tampoco pasé más tiempo investigando la función de esta estructura de datos, y aquí es principalmente para hacer una nota para recordarme.