2.5. Métodos de cadena y formato

Las cadenas vienen con una caja de herramientas integrada de métodos para inspeccionarlas y remodelarlas. Como las cadenas son inmutables, cada método devuelve una cadena nueva: la original no se modifica.

2.5.1. Inspeccionar cadenas

  • str.startswith() / str.endswith() – comprobación de prefijo o sufijo; devuelve un bool.

  • str.find() – posición de la primera aparición de una subcadena, o -1 si no está presente. str.index() hace lo mismo, pero provoca un ValueError si no la encuentra.

  • str.count() – número de apariciones no solapadas.

  • Palabra clave in"MV" in name devuelve True si la subcadena está en cualquier parte de la cadena.

>>> name = "OpenMV Cam"
>>> name.startswith("Open")
True
>>> name.find("MV")
4
>>> name.count("m")
1
>>> "Cam" in name
True

2.5.2. Limpieza y mayúsculas/minúsculas

  • str.strip() – elimina los espacios en blanco iniciales y finales. Pasa una cadena de caracteres para eliminar un conjunto personalizado (s.strip("/")).

  • str.lower() / str.upper() – conversión entre mayúsculas y minúsculas.

  • str.replace() – sustitución de subcadenas.

>>> "  hello  ".strip()
'hello'
>>> "abc-123".replace("-", "_")
'abc_123'
>>> "OpenMV".lower()
'openmv'

2.5.3. Dividir y unir

  • str.split() – divide una cadena en una lista en cada aparición de un separador (por defecto: cualquier secuencia de espacios en blanco).

  • str.join() – la operación inversa: une una secuencia de cadenas usando el receptor como separador. Esta es la forma eficiente de construir una cadena larga a partir de piezas.

>>> "1,2,3".split(",")
['1', '2', '3']
>>> "hello world".split()
['hello', 'world']
>>> ", ".join(["a", "b", "c"])
'a, b, c'

2.5.4. f-strings

La forma más sencilla de interpolar valores en una cadena es la f-string: un literal de cadena con el prefijo f. Cualquier expresión dentro de {} se evalúa e inserta:

>>> name = "OpenMV"
>>> count = 42
>>> f"{name} saw {count} blobs"
'OpenMV saw 42 blobs'

Dos puntos dentro de las llaves introducen una especificación de formato que controla cómo se representa el valor:

  • {x:.2f} – número de coma flotante con 2 dígitos tras el punto decimal.

  • {x:>10} – alineado a la derecha en un campo de 10 caracteres.

  • {x:<10} – alineado a la izquierda.

  • {x:0>4} – rellenado con ceros a la izquierda hasta un ancho de 4.

  • {x:#x} – hexadecimal con un prefijo 0x.

  • {x:b} – representación binaria.

>>> f"pi is roughly {3.14159:.3f}"
'pi is roughly 3.142'
>>> f"reg = {0xAB:#x}"
'reg = 0xab'
>>> for i in range(3):
...     print(f"line {i:0>3}")
line 000
line 001
line 002

Un único = tras el nombre de la expresión imprime tanto el nombre como el valor, práctico para impresiones rápidas de depuración:

>>> v = 3.14
>>> print(f"{v=}")
v=3.14

2.5.4.1. Conversiones de base de enteros

Tres funciones integradas hacen el mismo trabajo que las especificaciones de formato :b / :o / :x, pero devuelven directamente la cadena convertida:

  • bin() – base 2, con un prefijo "0b".

  • oct() – base 8, con un prefijo "0o".

  • hex() – base 16, con un prefijo "0x".

>>> hex(255)
'0xff'
>>> bin(10)
'0b1010'
>>> oct(8)
'0o10'

La dirección inversa – convertir una cadena en base N de vuelta a un entero – usa el constructor int con una base explícita:

>>> int("ff", 16)
255
>>> int("0b1010", 2)         # the "0b" prefix is allowed
10

Recurre a estas funciones cuando quieras la cadena en bruto de un entero (para una línea de registro, un archivo de configuración, un volcado de registros). Recurre a la especificación de formato cuando quieras relleno, ancho o mezclar el valor con otro texto en la misma f-string.

2.5.5. Estilos de formato más antiguos

Las f-strings son el estilo recomendado, pero todavía funcionan dos enfoques más antiguos que aparecen en el código existente:

str.format() – llaves con argumentos posicionales o por palabra clave pasados al método .format() sobre una cadena plantilla:

>>> "Hello, {}".format(name)
'Hello, OpenMV'
>>> "{0} + {0} = {1}".format(2, 4)
'2 + 2 = 4'
>>> "{name}: {value}".format(name="frames", value=42)
'frames: 42'

Las especificaciones de formato ({:.2f}, {:>10}, …) funcionan igual que en las f-strings; la única diferencia es dónde se suministra el valor.

Formato con % (estilo printf) – un único operador % sustituye valores en códigos de formato, un valor por código. Pasa varios valores como una tupla:

>>> "Hello, %s" % name
'Hello, OpenMV'
>>> "%d + %d = %d" % (2, 2, 4)
'2 + 2 = 4'
>>> "%.2f" % 3.14159
'3.14'

Los códigos de tipo más comunes son %s (cadena), %d (entero), %f (coma flotante) y %x (hexadecimal).

Cada código % puede llevar modificadores entre el % y la letra de tipo. La forma completa es %[flags][width][.precision]type:

  • width – número mínimo de caracteres que debe ocupar el campo. Los valores más cortos se rellenan con espacios; los más largos se desbordan. %10d reserva 10 caracteres y alinea el número a la derecha.

  • precision – su significado depende del tipo. Para números de coma flotante, el número de dígitos tras el punto decimal. %.2f da dos decimales. Para cadenas, el número máximo de caracteres a tomar (%.5s trunca a cinco).

  • Alineación a la izquierda – la bandera - coloca el campo a la izquierda. %-10d coloca los dígitos en el lado izquierdo con espacios finales.

  • Relleno con ceros – la bandera 0 rellena con ceros a la izquierda en lugar de espacios (para los tipos numéricos). %05d rellena con ceros hasta cinco dígitos.

  • Signo – la bandera + muestra siempre el signo en los números, incluido un + para los positivos.

  • Forma alternativa – la bandera #. Para %x esto antepone 0x a la salida; para %o antepone 0o.

Las banderas, el ancho y la precisión pueden combinarse:

>>> "%10d" % 42
'        42'                 # width 10, space-padded, right-aligned
>>> "%-10d|" % 42
'42        |'                # width 10, left-aligned
>>> "%05d" % 42
'00042'                      # width 5, zero-padded
>>> "%8.2f" % 3.14159
'    3.14'                   # width 8, 2 decimal places
>>> "%08.2f" % 3.14159
'00003.14'                   # width 8, zero-padded
>>> "%+d" % 42
'+42'                        # explicit sign
>>> "%#06x" % 0xAB
'0x00ab'                     # 0x prefix, zero-pad to 6 chars total

Ambos estilos antiguos son más lentos de leer y más propensos a errores que las f-strings: recurre a las f-strings en el código nuevo y reconoce las formas antiguas al leer código existente.