csv.QUOTE_STRINGS es un modo de comillas del módulo csv de Python pensado para hacer más explícita la diferencia entre texto y valores no textuales. Al escribir, los campos que son strings se guardan entre comillas, mientras que números y otros valores pueden quedar sin comillas. Al leer, los campos sin comillas pueden interpretarse de forma similar a QUOTE_NONNUMERIC, mientras que los campos citados permanecen como strings.
Esta característica resulta útil cuando un archivo CSV debe conservar la diferencia entre texto, números, cadenas vacías y valores ausentes sin una capa manual de serialización.
Por qué QUOTE_STRINGS es útil
CSV no tiene un sistema de tipos universal. El valor 42 puede ser un número, un código de producto, un identificador o un texto que debe conservar ceros iniciales. Muchos programas infieren tipos a partir de la sintaxis y pueden modificar los datos silenciosamente.
import csv
filas = [
["producto", "cantidad", "precio"],
["Curso de Python", 2, 149.9],
]
with open("ventas.csv", "w", newline="", encoding="utf-8") as archivo:
writer = csv.writer(archivo, quoting=csv.QUOTE_STRINGS)
writer.writerows(filas)
Las cadenas quedan citadas y los números permanecen sin comillas, ofreciendo una señal más clara al sistema consumidor.
Comparación con otros modos
QUOTE_MINIMAL cita solo los campos que contienen delimitadores, saltos de línea o caracteres especiales. QUOTE_ALL cita todos los campos. QUOTE_NONE evita comillas y suele requerir un carácter de escape. QUOTE_NONNUMERIC cita valores no numéricos e intenta convertir a float los campos no citados durante la lectura.
QUOTE_STRINGS se centra en strings de Python. Es una buena opción cuando el dominio distingue claramente texto y números y esa diferencia debe aparecer en el archivo.
Uso con DictWriter
import csv
registros = [
{"nombre": "Ana", "edad": 29, "saldo": 1250.50},
{"nombre": "Bruno", "edad": 34, "saldo": 980.00},
]
with open("clientes.csv", "w", newline="", encoding="utf-8") as archivo:
writer = csv.DictWriter(
archivo,
fieldnames=["nombre", "edad", "saldo"],
quoting=csv.QUOTE_STRINGS,
)
writer.writeheader()
writer.writerows(registros)
Este patrón funciona bien en exportaciones de APIs, informes administrativos, catálogos y archivos intercambiados entre servicios.
Lectura y conversión de tipos
El archivo debe respetar un contrato consistente. Los campos entre comillas permanecen como strings y los campos sin comillas pueden convertirse numéricamente.
import csv
with open("clientes.csv", newline="", encoding="utf-8") as archivo:
reader = csv.reader(archivo, quoting=csv.QUOTE_STRINGS)
for fila in reader:
print(fila)
La conversión implícita no reemplaza la validación. Comprueba cantidad de columnas, campos obligatorios, rangos, formatos y reglas del dominio.
Strings que parecen números
Códigos postales, teléfonos, números de pedido, SKU e identificadores suelen parecer números, pero deben seguir siendo texto.
datos = [
["codigo", "cantidad"],
["000127", 4],
]
Como "000127" es una string, queda entre comillas y es menos probable que un lector compatible lo transforme en 127.
None y campos vacíos
La representación de nulos debe documentarse. Según la versión de Python y el comportamiento del modo, None puede escribirse como un campo vacío sin comillas, mientras que una cadena vacía queda citada. Esto puede permitir distinguir dato ausente y texto vacío.
fila = [None, "", "texto", 0]
Prueba este comportamiento con las mismas versiones usadas en desarrollo, CI y producción. Las hojas de cálculo externas pueden perder la distinción.
Delimitadores y dialectos
El modo puede combinarse con punto y coma, terminadores personalizados y otras opciones.
with open("datos.csv", "w", newline="", encoding="utf-8") as archivo:
writer = csv.writer(
archivo,
delimiter=";",
quoting=csv.QUOTE_STRINGS,
lineterminator="\n",
)
writer.writerow(["item", "valor"])
writer.writerow(["Suscripcion", 99.9])
Define delimitador, codificación y salto de línea de forma explícita cuando otro sistema consuma el archivo.
Normalizar antes de exportar
Fechas, decimales, enums y objetos personalizados no tienen una representación CSV universal.
from datetime import date
from decimal import Decimal
def serializar(valor):
if isinstance(valor, Decimal):
return format(valor, "f")
if isinstance(valor, date):
return valor.isoformat()
return valor
Convertir un decimal a string hará que quede entre comillas. Puede ser deseable para preservar precisión, pero quizá el consumidor lo trate como texto. Decide el contrato antes de exportar.
Pruebas de ida y vuelta
Una prueba confiable escribe una fila, la lee y compara valores y tipos.
import csv
import io
def roundtrip(fila):
buffer = io.StringIO(newline="")
writer = csv.writer(buffer, quoting=csv.QUOTE_STRINGS)
writer.writerow(fila)
buffer.seek(0)
return next(csv.reader(buffer, quoting=csv.QUOTE_STRINGS))
Incluye comas, comillas, saltos de línea, Unicode, None, strings vacías, números negativos, notación científica e identificadores con ceros iniciales.
Riesgos con hojas de cálculo
Excel y otras aplicaciones pueden eliminar ceros iniciales, convertir identificadores largos a notación científica o reinterpretar fechas. También pueden ejecutar fórmulas en celdas que empiezan con =, +, - o @. Evalúa el riesgo de CSV injection y aplica la política de seguridad adecuada.
Uso en pipelines
Para recorrer archivos, consulta pathlib.Path.walk en Python. Para identificar tipos, revisa mimetypes.guess_file_type en Python. Para workers, consulta queue.SimpleQueue en Python. Para modelos más claros, revisa dataclasses.KW_ONLY en Python.
Compatibilidad de versiones
csv.QUOTE_STRINGS es una característica relativamente reciente. Confirma la versión mínima de Python del proyecto. Si necesitas versiones antiguas, crea una capa de compatibilidad que preprocese campos o use otro modo.
La documentación oficial de csv es la referencia principal. Para convenciones generales del formato, consulta RFC 4180.
Buenas prácticas operativas
Documenta delimitador, codificación, representación de nulos, política de comillas y reglas de tipos. Mantén ejemplos válidos bajo control de versiones. Registra errores con número de línea sin exponer información sensible.
Al importar archivos no confiables, limita tamaño, filas, columnas y longitud máxima de campos. Valida los valores después del parsing y no supongas que las comillas hacen seguro el contenido.
Conclusión
csv.QUOTE_STRINGS permite citar texto y dejar valores no textuales sin comillas. Puede preservar identificadores con ceros iniciales, mostrar la intención de tipos y mejorar la interoperabilidad cuando productor y consumidor comparten las reglas.
Úsalo con esquemas explícitos, pruebas de ida y vuelta, semántica de nulos documentada y cuidado con hojas de cálculo. CSV sigue siendo texto; la confiabilidad depende de un contrato claro.







