Skip to content
This page has been auto-translated and may contain errors.View in English

Saída e entrada

docs.scrimba.com

Duas ferramentas que você usará desde a primeira linha que escrever: print() mostra valores no terminal, input() obtém texto do usuário. São simples, mas saber como funcionam o salva de alguns problemas no início.

print() e input() são as funções padrão de E/S do terminal do Python. Ambas são mais configuráveis do que parecem à primeira vista. print() aceita argumentos que controlam como os valores são unidos e onde a saída termina. input() sempre retorna uma string, o que molda como você lida com cada valor que vem do usuário.

Nos bastidores, print() escreve em sys.stdout e input() lê de sys.stdin (os fluxos padrão de saída e entrada aos quais seu terminal está conectado). Ambos lidam apenas com texto, e a saída é armazenada em buffer por padrão: Python a mantém brevemente e escreve em pedaços em vez de um caractere por vez. Duas consequências importam em programas reais: a saída vai para um fluxo diferente dos erros (stdout versus stderr), e você pode forçar esse buffer a esvaziar quando precisar que a saída apareça imediatamente.

Como Python executa seu código

Python executa seu código de cima para baixo, uma linha por vez, exatamente na ordem em que você o escreveu. Sem pulos. A ordem em que você escreve as coisas é a ordem em que são executadas. Sempre.

python
cidade = "São Paulo"
print(cidade)
print("População: 12 milhões")

cidade é atribuída primeiro. O primeiro print é executado. O segundo print é executado. Sempre, nessa ordem.

Isso importa porque você não pode usar uma variável antes de atribuir um valor a ela. Python ainda não a viu e gerará um erro:

python
print(país)   # NameError: país não foi definido ainda
país = "Brasil"

Lembre-se disso conforme seus programas crescem: tudo que você usar deve ser definido antes de usá-lo.

Python usa execução sequencial: cada declaração é avaliada conforme é encontrada, em uma única passagem de cima para baixo pelo arquivo. Não há pré-leitura de todo o arquivo primeiro. Referenciar um nome antes de atribuir um valor a ele gera NameError exatamente naquela linha, não antes.

python
cidade = "São Paulo"
print(cidade)             # funciona: cidade já foi definida
print(país)               # NameError: ainda não foi atribuído
país = "Brasil"

A regra: as dependências devem ser definidas antes da linha que as usa.

Python executa seu arquivo em uma única passagem de cima para baixo, e só procura um nome no momento em que a linha realmente é executada, não quando primeiro lê o arquivo. É por isso que um nome ausente é um NameError em tempo de execução (quando a linha é executada) em vez de um erro no instante em que você salva. Não há hoisting (a forma como JavaScript silenciosamente move declarações var para o topo de seu escopo) e nenhuma declaração antecipada (a forma como C permite prometer um nome agora e defini-lo depois). Um nome existe no momento em que é atribuído, e qualquer uso antes disso gera um erro.

python
print(país)      # NameError em tempo de execução, não um erro de sintaxe
país = "Brasil"
JunoComo Python executa seu código Python lê seu arquivo de cima para baixo, uma linha por vez, na ordem em que você o escreveu. O porém que pega todo mundo uma vez: um nome tem que existir antes da linha que o usa, ou você recebe um NameError. Sem pulos, sem ler o arquivo todo primeiro.
JunoComo Python executa seu código De cima para baixo, uma passagem, em ordem. Um nome tem que ser atribuído antes de qualquer linha que o usa, senão é um NameError exatamente naquela linha. Sem pré-leitura do arquivo.
JunoComo Python executa seu código Uma passagem de cima para baixo, nomes procurados conforme cada linha é executada. Use um nome antes de ser atribuído e você recebe um NameError em tempo de execução, não um erro de sintaxe. Python não faz hoisting e não tem declarações antecipadas, então a ordem realmente é tudo.

Imprimindo saída

print() é como Python fala de volta com você. Passe qualquer valor para ele e esse valor é exibido. Ele converte automaticamente o que você dá em texto.

print() converte cada argumento em uma string via str(), os une com um separador (um espaço por padrão), e depois escreve o resultado seguido de uma quebra de linha para a saída padrão. Compreender os padrões torna os argumentos opcionais mais previsíveis.

A assinatura completa de print() é print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False). O coletor *objects aceita qualquer número de argumentos posicionais e chama str() em cada um. sep e end controlam a formatação; file redireciona a saída para qualquer fluxo gravável; flush força o buffer a esvaziar imediatamente.

python
print("Olá")    # Olá
print(42)       # 42
print(3.14)     # 3.14
print(True)     # True

Múltiplos valores

Você pode imprimir múltiplos valores de uma vez separando-os com vírgulas. Python coloca um espaço entre eles por padrão. Mude o separador com sep:

Múltiplos argumentos posicionais são cada um convertidos com str() individualmente, e depois unidos por sep. O sep padrão é um único espaço. Sobrescrevê-lo permite produzir saída formatada sem concatenação de strings:

print() não constrói uma string e a escreve; escreve cada argumento no fluxo por sua vez (chamando str() em cada um), com sep entre e end por último. Como essas escritas acontecem uma por vez em vez de como uma única operação bloqueada, duas chamadas print() executando ao mesmo tempo (em threads diferentes) podem intercalar sua saída. Quando isso importa, construa uma string e a imprima uma vez. Para uso cotidiano, sobrescrever sep ainda vence colar strings juntas à mão:

python
nome = "Maria"
idade = 28
print(nome, idade)                      # Maria 28
print("Nome:", nome)                    # Nome: Maria
print("2024", "01", "15", sep="-")     # 2024-01-15
print("a", "b", "c", sep=", ")         # a, b, c

Controlando o final da linha

Cada chamada print() termina com uma quebra de linha por padrão, então a próxima saída começa em uma linha fresca. Mude isso com end. Definir end="" faz o próximo print continuar na mesma linha:

O parâmetro end substitui a quebra de linha padrão. Defina como "" para suprimir a quebra de linha, como " " para ficar na mesma linha com um espaço, ou como qualquer outra string. Combinado com sep, você pode produzir a maioria dos formatos de saída sem construir strings manualmente:

sep e end são apenas por palavra-chave (você os passa por nome, como end="", nunca por posição), com padrão de um espaço e uma quebra de linha. end="" é a forma padrão de imprimir uma linha parcial e deixar a próxima chamada continuá-la. Para saída que precisa aparecer conforme acontece, como um indicador de progresso ou um log ao vivo, adicione flush=True para que Python escreva imediatamente em vez de esperar por uma quebra de linha ou pelo buffer encher.

python
print("Carregando", end="")
print("...")
# Carregando...

print("um", end=" | ")
print("dois", end=" | ")
print("três")
# um | dois | três
JunoImprimindo saídaprint() transforma o que você dá em texto e mostra. Passe várias coisas separadas por vírgulas e você recebe um espaço entre elas, mude com sep. Cada print cai para uma nova linha no final; end="" mantém o próximo na mesma linha.
JunoImprimindo saídaprint() executa str() em cada argumento, os une com sep (um espaço por padrão), e termina com end (uma quebra de linha por padrão). Sobrescreva um ou outro para formatar saída sem colar strings juntas.
JunoImprimindo saídaprint() escreve cada argumento por str(), com sep entre e end por último, ambos apenas por palavra-chave. Use end="" para continuar uma linha, e flush=True quando a saída precisa aparecer agora.

Formatando saída com f-strings

A forma mais limpa de construir mensagens é f-strings. Coloque f antes da aspas de abertura, e depois envolva qualquer variável ou expressão em chaves. Python preenche em tempo de execução. Você pode colocar qualquer valor, cálculo ou chamada de método dentro de {}.

f-strings avaliam qualquer expressão dentro de {} em tempo de execução e incorporam o resultado como uma string. Um dois-pontos depois do valor introduz uma especificação de formato: uma sintaxe compacta para controlar casas decimais, alinhamento e formatação de números. Elas são mais rápidas e legíveis que concatenação, e não exigem chamadas explícitas a str().

Cada {} em uma f-string acaba chamando format(value, spec), que passa para o método próprio __format__ do valor (um dunder, o método com duplo-sublinhado que Python chama para formatar um valor). Então qualquer classe pode decidir como fica dentro de uma f-string definindo __format__. Os sinalizadores de conversão !r, !s e !a executam repr(), str() ou ascii() no valor primeiro; !r é o que vale lembrar para depuração, porque mostra um valor da forma que você o escreveria em código (aspas, escapes e tudo), mostrado na prática abaixo.

python
nome = "Maria"
pontuação = 980

# concatenação: desajeitada, exige str() para números
print("Jogador: " + nome + ", Pontuação: " + str(pontuação))

# f-string: legível, sem conversão manual
print(f"Jogador: {nome}, Pontuação: {pontuação}")

Você pode colocar qualquer expressão dentro de {}: aritmética, chamadas de método (como .upper(), coberto completamente no capítulo Strings), especificações de formato:

python
preço = 49.99
imposto = 0.2
total = preço * (1 + imposto)

print(f"Total: {total:.2f}")             # Total: 59.99
print(f"Nome: {nome.upper()}")           # Nome: MARIA
print(f"2 + 2 = {2 + 2}")                # 2 + 2 = 4

A especificação de formato depois de : controla como o valor é exibido:

python
razão = 0.8765
contagem = 1234567
rótulo = "receita"

print(f"{razão:.1%}")       # 87.6%
print(f"{contagem:,}")      # 1.234.567
print(f"{rótulo:>12}")      # "     receita"

:.2f significa "duas casas decimais". Você usará isso constantemente para preços e medidas. Tudo mais está lá quando você precisar. A coisa principal: qualquer coisa pode ir dentro de {}, não apenas nomes de variáveis.

:.2f e :.0% cobrem a maioria das necessidades de formatação. Os especificadores de alinhamento (>, <, ^) com uma largura produzem saída tabular arrumada. O padrão geral é {value:[align][width][.precision][type]}. Uma vez que você reconhece as partes, qualquer especificação é legível sem memorizar todas as combinações.

A mesma especificação pode significar coisas diferentes para tipos diferentes, porque cada tipo se formata. f"{'oi':5}" preenche texto à direita (texto se alinha à esquerda por padrão) enquanto f"{42:5}" preenche à esquerda (números se alinham à direita): mesmo :5, resultado oposto. Cada tipo interno carrega suas próprias regras para essa mini-linguagem de formato, e uma classe personalizada define as suas definindo __format__.

JunoFormatando saída com f-strings Coloque f antes da aspas de abertura e envolva qualquer coisa em {}: uma variável, uma soma, até mesmo uma chamada de método. Dois-pontos adicionam formatação, como :.2f para duas casas decimais. Muito mais limpo do que colar strings juntas com +.
JunoFormatando saída com f-stringsf"..." coloca o resultado de qualquer expressão direto na string, sem str() necessário. Depois de dois-pontos vem a especificação de formato: :.2f, :,, :>12 e companhia. Mais limpo e rápido que concatenação.
JunoFormatando saída com f-strings Cada {} chama o próprio __format__ do valor, então a especificação depois do dois-pontos significa o que esse tipo decide. !r é o que vale lembrar: mostra um valor da forma que você o digitaria, o que torna espaços à direita e outra porcaria invisível aparecer quando você está depurando.

Obtendo entrada do usuário

input() pausa seu programa e espera o usuário digitar algo. Seja o que for que ele digitar (e pressionar Enter) volta como o valor de retorno. A string entre os parênteses é o prompt que o usuário vê.

python
nome = input("Qual é o seu nome? ")
print(f"Olá, {nome}!")

input() sempre retorna uma string, não importa o que o usuário digitar. Digite 42 e você recebe "42", não o número 42. Para fazer aritmética com isso, converta explicitamente:

python
idade = int(input("Quantos anos você tem? "))
print(f"Em dez anos você terá {idade + 10}.")

E se o usuário digitar algo que não pode ser convertido? Python gera um ValueError. Lidar com isso apropriadamente é coberto no capítulo Files and exceptions.

input() escreve o prompt para a saída padrão, lê uma linha da entrada padrão, remove a quebra de linha à direita, e retorna o resultado como uma string. Não há inferência de tipo. Tudo do terminal chega como texto; você declara qual tipo você precisa convertendo explicitamente na fronteira.

python
nome = input("Qual é o seu nome? ")
idade = int(input("Quantos anos você tem? "))

Este padrão (receba texto, converta para o tipo que você precisa) se aplica em todo lugar onde dados externos chegam. int(), float() e str() são as ferramentas de conversão. Se a string não puder ser convertida, Python gera ValueError, coberto no capítulo Files and exceptions.

input() é um invólucro fino: escreve o prompt para sys.stdout (saída padrão), o esvazia para que o prompt apareça antes do programa se bloquear, lê uma linha de sys.stdin (entrada padrão), remove a quebra de linha à direita, e devolve uma str. É sempre uma str por design, porque Python não pode adivinhar se "42" era pretendido como um inteiro, um float, ou texto literal. Então você converte na fronteira. Esta é a forma fundamental da E/S do Python: dados externos chegam como texto, e seu código decide seu tipo no ponto de entrada.

python
nome = input("Digite seu nome: ")
pontuação = float(input("Digite sua pontuação (0.0 a 1.0): "))

print(f"Nome:      {nome!r}")       # !r revela qualquer espaço invisível
print(f"Pontuação: {pontuação:.1%}")
JunoObtendo entrada do usuárioinput() mostra seu prompt, espera por uma linha, e sempre a devolve como uma string, mesmo se digitarem um número. Precisa de um número? Converta você mesmo com int() ou float() conforme chega, e continue com o tipo correto.
JunoObtendo entrada do usuárioinput() sempre retorna uma str, sem inferência de tipo. Converta na fronteira com int() ou float(), e espere um ValueError se o texto não analisar. Esse padrão receba-depois-converta aparece em todo lugar onde dados externos chegam.
JunoObtendo entrada do usuário Tudo de input() é uma str por design, porque Python não pode adivinhar o que você quis dizer. Converta no ponto de entrada e trate o ValueError quando não puder analisar. Mesma forma que todo outro lugar onde dados externos chegam.

Escrevendo para stderr

Por padrão, print() escreve para saída padrão: o fluxo que aparece no terminal e flui em pipes. Python também tem erro padrão, um fluxo separado para diagnósticos e avisos. Parecem idênticos em um terminal mas são distintos: quando você coloca a saída de um script em pipe para outro comando, apenas stdout passa. Stderr sempre chega ao terminal.

Escrever para stderr usa o argumento file de print(). Isso exige importar sys, que é coberto no capítulo Modules. Por enquanto, saber que os dois fluxos existem e por que são separados é suficiente.

Na prática

Um quiz que se personaliza a partir da entrada do usuário:

python
nome = input("Qual é o seu nome? ")
assunto = input("Qual assunto? ")

print(f"Tudo bem, {nome}. Começando seu quiz de {assunto}.")
print("Boa sorte!")

Ambas as entradas voltam como strings e entram diretamente nas f-strings. Nenhuma conversão necessária porque você está usando-as como texto, não números.

Um conversor de temperatura com saída tabular alinhada:

python
celsius = float(input("Temperatura em Celsius: "))
fahrenheit = celsius * 9 / 5 + 32

print(f"{'Celsius':>12} {'Fahrenheit':>12}")
print(f"{celsius:>12.1f} {fahrenheit:>12.1f}")

float() lida com inteiros e decimais do usuário. A especificação >12 mantém as colunas alinhadas independentemente de quantos dígitos os números tenham. Tente digitar 100 e -40: a saída permanece arrumada de qualquer forma.

Usando !r para revelar exatamente o que Python recebeu, útil quando a saída parece errada:

python
nome = input("Digite seu nome: ")
pontuação = float(input("Digite sua pontuação (0.0 a 1.0): "))

print(f"Nome:      {nome!r}")
print(f"Pontuação: {pontuação!r}")
print()
print(f"Resultado: {nome}: {pontuação:.1%}")

{nome} e {nome!r} exibem identicamente quando a entrada é limpa. A diferença aparece quando há espaços à direita ou outros caracteres invisíveis. Pegar o hábito de !r durante depuração torna valores inesperados visíveis imediatamente.