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

Saída e entrada

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 conhecer como se comportam poupa você de algumas surpresas logo no começo.

print() e input() são as funções padrão de I/O do terminal do Python. Ambas são mais configuráveis do que parecem à primeira vista. print() aceita argumentos que controlam como 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 nos quais seu terminal está conectado). Ambos lidam apenas com texto, e a saída é buffered por padrão: Python a mantém brevemente e escreve em blocos em vez de um caractere por vez. Duas consequências importam em programas reais: a saída vai para um fluxo diferente do dos erros (stdout versus stderr), e você pode forçar esse buffer a descarregar 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 que você escreveu. Sem pulos. A ordem que você escreve as coisas é a ordem que elas rodam. Sempre.

python
city = "Brasília"
print(city)
print("População: 3 milhões")

city é atribuída primeiro. O primeiro print roda. O segundo print roda. Sempre, nessa ordem.

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

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

Tenha isso em mente conforme seus programas crescem: qualquer coisa que você use deve ser definida antes de usá-la.

Python usa execução sequencial: cada comando é avaliado conforme é encontrado, em uma única passagem de cima para baixo pelo arquivo. Não há uma pré-verificação do arquivo inteiro primeiro. Referenciar um nome antes dele ser atribuído gera NameError exatamente naquela linha, não antes.

python
city = "Brasília"
print(city)             # funciona: city já está atribuída
print(country)          # NameError: ainda não foi atribuída
country = "Brasil"

A regra: 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 aquela linha realmente roda, não quando primeiro lê o arquivo. É por isso que um nome faltante é um NameError em tempo de execução (quando a linha é executada) em vez de um erro no instante que você salva. Não há hoisting (a maneira que JavaScript silenciosamente move declarações var para o topo de seu escopo) e não há declarações antecipadas (a maneira que C deixa você 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(country)   # NameError em tempo de execução, não um erro de sintaxe
country = "Brasil"
JunoComo Python executa seu código Python lê seu arquivo de cima para baixo, uma linha por vez, na ordem que você escreveu. O detalhe que pega todo mundo uma vez: um nome tem que existir antes da linha que o usa, ou você pega um NameError. Sem pular à frente, sem ler o arquivo inteiro 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 naquela linha exata. Sem pré-verificação do arquivo.
JunoComo Python executa seu código Uma passagem de cima para baixo, nomes procurados conforme cada linha roda. Use um nome antes dele ser atribuído e você pega 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 para você. Passe qualquer valor e ele exibe esse valor. Converte automaticamente o que você der para texto.

print() converte cada argumento para uma string via str(), une-os com um separador (um espaço por padrão), e escreve o resultado seguido de uma quebra de linha para a saída padrão. Entender 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 descarregar imediatamente.

python
print("Hello")    # Hello
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, depois unidos por sep. O sep padrão é um único espaço. Sobrescrevê-lo deixa você 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 vez (chamando str() em cada um), com sep no meio e end por último. Como essas escritas acontecem uma por vez em vez de como uma operação trancada única, dois print() rodando ao mesmo tempo (em threads diferentes) podem intercalar sua saída. Quando isso importa, construa uma string e imprima-a uma vez. Para uso cotidiano, sobrescrever sep ainda bate colar strings manualmente:

python
name = "Maria"
age = 28
print(name, age)                        # Maria 28
print("Name:", name)                    # Name: Maria
print("2024", "01", "15", sep="-")     # 2024-01-15
print("a", "b", "c", sep=", ")         # a, b, c

Controlando o fim da linha

Cada chamada a 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-o para "" para suprimir a quebra de linha, para " " para ficar na mesma linha com um espaço, ou para 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 pelo 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 em tempo real, adicione flush=True para que Python escreva imediatamente em vez de esperar uma quebra de linha ou seu buffer preencher.

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

print("one", end=" | ")
print("two", end=" | ")
print("three")
# one | two | three
JunoImprimindo saídaprint() transforma o que você der em texto e o mostra. Passe várias coisas separadas por vírgulas e você pega um espaço entre elas, mude isso com sep. Cada print cai para uma nova linha no final; end="" mantém o próximo na mesma linha.
JunoImprimindo saídaprint() roda str() em cada argumento, une-os 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 manualmente.
JunoImprimindo saídaprint() escreve cada argumento através de str(), com sep no meio e end por último, ambos apenas por palavra-chave. Recorra a end="" para continuar uma linha, e a flush=True quando a saída precisa aparecer agora mesmo.

Formatando saída com f-strings

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

f-strings avaliam qualquer expressão dentro de {} em tempo de execução e incorporam o resultado como uma string. Uma vírgula após o 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 requerem chamadas explícitas a str().

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

python
name = "Maria"
score = 980

# concatenação: desajeitada, requer str() para números
print("Player: " + name + ", Score: " + str(score))

# f-string: legível, sem conversão manual
print(f"Player: {name}, Score: {score}")

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
price = 49.99
tax = 0.2
total = price * (1 + tax)

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

A especificação de formato após : controla como o valor é exibido:

python
ratio = 0.8765
count = 1234567
label = "revenue"

print(f"{ratio:.1%}")       # 87.6%
print(f"{count:,}")         # 1,234,567
print(f"{label:>12}")       # "     revenue"

:.2f significa "duas casas decimais". Você usará constantemente para preços e medidas. Tudo mais está lá quando você precisa. A coisa principal: qualquer coisa pode ir dentro de {}, não só 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ê reconheça 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 a si mesmo. f"{'hi':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 integrado carrega suas próprias regras para essa mini-linguagem de formato, e uma classe customizada define as suas ao definir __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é uma chamada de método. Uma vírgula adiciona formatação, como :.2f para duas casas decimais. Muito mais limpo que colar strings juntas com +.
JunoFormatando saída com f-stringsf"..." derruba o resultado de qualquer expressão direto na string, sem str() necessário. Após uma vírgula 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 após a vírgula significa o que aquele tipo decidir. !r é o para lembrar: mostra um valor da forma como você o digitaria, o que torna espaços à direita e outras coisas invisíveis se destacarem quando você está debugando.

Obtendo entrada do usuário

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

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

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

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

E se o usuário digitar algo que não pode ser convertido? Python gera um ValueError. Lidar com isso adequadamente é coberto no capítulo Arquivos e exceções.

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
name = input("Qual é o seu nome? ")
age = int(input("Quantos anos você tem? "))

Esse padrão (receber texto, converter para o tipo que você precisa) se aplica em qualquer lugar onde dados externos chegam. int(), float() e str() são as ferramentas de conversão. Se a string não pode ser convertida, Python gera ValueError, coberto no capítulo Arquivos e exceções.

input() é um wrapper fino: escreve o prompt em sys.stdout (saída padrão), o descarrega para que o prompt apareça antes do programa 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 consegue adivinhar se "42" foi feito para ser um inteiro, um float ou texto literal. Então você converte na fronteira. Esta é a forma fundamental do I/O do Python: dados externos chegam como texto, e seu código decide seu tipo no ponto de entrada.

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

print(f"Name:  {name!r}")      # !r revela qualquer espaço em branco invisível
print(f"Score: {score:.1%}")
JunoObtendo entrada do usuárioinput() mostra seu prompt, espera uma linha, e sempre a devolve como uma string, mesmo se eles digitarem um número. Precisa de um número? Converta você mesmo com int() ou float() conforme chega, depois 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 for analisável. Aquele padrão receber-então-converter aparece em qualquer lugar onde dados externos chegam.
JunoObtendo entrada do usuário Tudo de input() é uma str por design, porque Python não consegue adivinhar o que você quis dizer. Converta no ponto de entrada e lide com o ValueError quando não for analisável. Mesma forma que qualquer 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. Eles parecem idênticos em um terminal mas são distintos: quando você direciona a saída de um script para outro comando, apenas stdout passa por. Stderr sempre chega ao terminal.

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

Na prática

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

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

print(f"Ok, {name}. Iniciando seu quiz de {subject}.")
print("Boa sorte!")

Ambas as entradas voltam como strings e vão direto para as f-strings. Nenhuma conversão necessária porque você as está usando 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 colunas alinhadas não importa quantos dígitos os números tenham. Tente digitar 100 e -40: a saída fica arrumada de qualquer forma.

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

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

print(f"Name:   {name!r}")
print(f"Score:  {score!r}")
print()
print(f"Result: {name}: {score:.1%}")

{name} e {name!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 debugging torna valores inesperados visíveis imediatamente.