csv.QUOTE_STRINGS: conserva tipos en archivos CSV

Publicado el: 15/09/2026
Tempo de leitura: 5 minutos
Análisis de datos CSV con csv.QUOTE_STRINGS en Python

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.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Código y rutas de archivos para PurePath.full_match en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    PurePath.full_match: valida rutas con patrones glob

    Aprende PurePath.full_match en Python para validar rutas completas con patrones glob, controlar mayúsculas y crear filtros precisos.

    Ler mais

    Tempo de leitura: 6 minutos
    15/09/2026
    Código asíncrono que representa asyncio.eager_task_factory en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    asyncio.eager_task_factory: reduce overhead de tareas

    Aprende asyncio.eager_task_factory en Python para reducir overhead, entender cambios de orden y optimizar corrutinas cortas con seguridad.

    Ler mais

    Tempo de leitura: 5 minutos
    14/09/2026
    Desarrollador trabajando con timestamps UTC y calendar.timegm en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    calendar.timegm: convierte UTC a timestamp Unix

    Aprende calendar.timegm en Python para convertir fechas UTC en timestamps Unix y evitar errores de zona horaria y unidades.

    Ler mais

    Tempo de leitura: 6 minutos
    14/09/2026
    Programador analizando código para identificar tipos MIME de archivos con Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    mimetypes.guess_file_type: detecta tipos MIME

    Aprende mimetypes.guess_file_type en Python para detectar tipos MIME en rutas, URLs, uploads y respuestas HTTP con fallbacks seguros.

    Ler mais

    Tempo de leitura: 4 minutos
    13/09/2026
    Componentes de servidor que representan intérpretes Python aislados ejecutándose en paralelo
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    InterpreterPoolExecutor: paralelismo real en Python

    Aprende InterpreterPoolExecutor en Python para tareas CPU-bound, intérpretes aislados, paralelismo real y concurrencia segura.

    Ler mais

    Tempo de leitura: 6 minutos
    13/09/2026
    Microprocesador que representa las CPU disponibles para un proceso Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    os.process_cpu_count: cuenta CPUs disponibles

    Aprende os.process_cpu_count en Python para dimensionar workers según las CPU disponibles para el proceso.

    Ler mais

    Tempo de leitura: 4 minutos
    12/09/2026