2.5. Métodos de string e formatação

As strings vêm com uma caixa de ferramentas integrada de métodos para inspeção e reformatação. Como as strings são imutáveis, cada método devolve uma nova string – o original fica inalterado.

2.5.1. Inspecionar strings

  • str.startswith() / str.endswith() – teste de prefixo ou sufixo; devolve bool.

  • str.find() – posição da primeira ocorrência de uma substring, ou -1 se ausente. str.index() faz o mesmo mas lança ValueError quando ausente.

  • str.count() – número de ocorrências não sobrepostas.

  • Palavra-chave in"MV" in name devolve True se a substring estiver em qualquer lugar da string.

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

2.5.2. Limpar e converter maiúsculas/minúsculas

  • str.strip() – remover espaços em branco iniciais e finais. Passe uma string de caracteres para remover um conjunto personalizado (s.strip("/")).

  • str.lower() / str.upper() – conversão de maiúsculas/minúsculas.

  • str.replace() – substituição de substrings.

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

2.5.3. Dividir e juntar

  • str.split() – separar uma string numa lista em cada ocorrência de um separador (por defeito: qualquer sequência de espaços em branco).

  • str.join() – o inverso: juntar uma sequência de strings com o recetor como separador. Esta é a forma eficiente de construir uma string longa a partir de partes.

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

2.5.4. f-strings

A forma mais simples de interpolar valores numa string é a f-string – um literal de string prefixado com f. Qualquer expressão dentro de {} é avaliada e inserida:

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

Um dois-pontos dentro das chavetas introduz uma especificação de formato que controla como o valor é apresentado:

  • {x:.2f} – número de vírgula flutuante com 2 casas decimais.

  • {x:>10} – alinhar à direita num campo de 10 caracteres.

  • {x:<10} – alinhar à esquerda.

  • {x:0>4} – preencher com zeros à esquerda até largura 4.

  • {x:#x} – hexadecimal com prefixo 0x.

  • {x:b} – representação binária.

>>> 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

Um único = após o nome da expressão imprime tanto o nome como o valor – prático para impressões de depuração rápidas:

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

2.5.4.1. Conversões de bases de inteiros

Três funções integradas fazem o mesmo trabalho que as especificações de formato :b / :o / :x mas devolvem diretamente a string convertida:

  • bin() – base 2, com prefixo "0b".

  • oct() – base 8, com prefixo "0o".

  • hex() – base 16, com prefixo "0x".

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

A direção inversa – transformar uma string de base N de volta num inteiro – usa o construtor int com uma base explícita:

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

Recorra a estas quando quiser a string bruta de um int (para uma linha de registo, um ficheiro de configuração, um dump de registo). Recorra à especificação de formato quando quiser preenchimento, largura, ou misturar o valor com outro texto na mesma f-string.

2.5.5. Estilos de formatação mais antigos

As f-strings são o estilo recomendado, mas duas abordagens mais antigas ainda funcionam e aparecem no código existente:

str.format() – chavetas com argumentos posicionais ou por palavra-chave passados ao método .format() numa string de modelo:

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

As especificações de formato ({:.2f}, {:>10}, …) funcionam da mesma forma que nas f-strings; a única diferença é onde o valor é fornecido.

Formatação com % (estilo printf) – um único operador % substitui valores em códigos de formato, um valor por código. Passe múltiplos valores como uma tupla:

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

Os códigos de tipo mais comuns são %s (string), %d (inteiro), %f (número de vírgula flutuante), e %x (hexadecimal).

Cada código % pode ter modificadores entre o % e a letra de tipo. A forma completa é %[flags][width][.precision]type:

  • width – número mínimo de caracteres que o campo deve ocupar. Valores mais curtos são preenchidos com espaços; valores mais longos transbordam. %10d reserva 10 caracteres e alinha o número à direita.

  • precision – o significado depende do tipo. Para números de vírgula flutuante, o número de dígitos após a vírgula decimal. %.2f dá duas casas decimais. Para strings, o número máximo de caracteres a usar (%.5s trunca para cinco).

  • Alinhar à esquerda – o sinalizador - coloca o campo à esquerda. %-10d coloca os dígitos no lado esquerdo com espaços a seguir.

  • Preencher com zeros – o sinalizador 0 preenche com zeros à esquerda em vez de espaços (para tipos numéricos). %05d preenche com zeros até cinco dígitos.

  • Sinal – o sinalizador + mostra sempre o sinal nos números, incluindo um + para os positivos.

  • Forma alternativa – o sinalizador #. Para %x este prefixa a saída com 0x; para %o prefixa 0o.

Os sinalizadores, a largura e a precisão podem ser combinados:

>>> "%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 os estilos mais antigos são mais lentos de ler e mais propensos a erros do que as f-strings – recorra a f-strings no novo código, e reconheça as formas mais antigas ao ler código existente.