Capítulo 12, Básico
Conversão de tipos e valores falsy
Converter tipos é rotina. O que costuma pegar iniciante é não saber o que o Python considera verdadeiro ou falso.
Código deste capítulo: basico/cap12_conversao_falsy.py
Conversão explícita
As funções int(), float(), str() e bool() convertem de forma explícita. Duas surpresas: int() trunca em direção ao zero, e round() arredonda para o número par mais próximo quando o valor está exatamente no meio:
print(int("42") + 1)
print(float("3.5") * 2)
print(str(10) + " anos")
print(int(3.9), int(-3.9))
print(round(3.5), round(4.5), round(3.14159, 2))
43
7.0
10 anos
3 -3
4 4 3.14
Quando o texto não é conversível, o Python levanta ValueError, e a mensagem diz exatamente qual era o valor:
try:
int("abc")
except ValueError as erro:
print(erro)
invalid literal for int() with base 10: 'abc'
Conversão implícita
O Python converte sozinho quando a conta pede, sempre para o tipo mais "largo". O operador / é um caso à parte: ele sempre devolve float, mesmo quando as duas pontas são inteiras. Para divisão inteira use //:
print(1 + 2.5)
print(True + 1)
print(type(6 / 2), type(6 // 2))
3.5
2
<class 'float'> <class 'int'>
Valores falsy
Em uma condição, o Python converte o valor com bool(). A regra é curta: valores "vazios" ou "zero" são falsos, e todo o resto é verdadeiro. Esta é a lista completa dos que você mais encontra:
valores = [None, False, 0, 0.0, "", [], (), {}, set(), range(0)]
print([bool(v) for v in valores])
[False, False, False, False, False, False, False, False, False, False]
Todos dão False. Repare que None está na lista, e é o falso mais frequente em código real. Já estes são verdadeiros, e surpreendem:
print(bool("0"), bool("False"), bool([0]), bool(" "))
True True True True
A string "0", a string "False", uma lista que contém zero e uma string com espaço são todas verdadeiras, porque não estão vazias.
Falsy não é o mesmo que None
O idioma if not valor mistura "vazio" com "zero" com "ausente". Quando a distinção importa, compare com None explicitamente:
def descricao(quantidade):
if quantidade is None:
return "não informado"
if not quantidade:
return "zero"
return f"{quantidade} unidades"
print(descricao(None))
print(descricao(0))
print(descricao(5))
não informado
zero
5 unidades
Se eu escrevesse apenas if not quantidade, None e 0 caíam no mesmo ramo, e o sistema trataria "não informado" como "zero". Em estoque, isso é um bug de verdade.
Exercício 1
Números no formato brasileiro
Escreva para_float(texto) que converta "12,5" em 12.5 e "1.234,56" em 1234.56.