Entrada e Saída de Dados em Python

Anteriormente, quando estávamos estudando o que é um programa de computador, aprendemos que todo programa possui três componentes básicos: uma entrada específica, uma sequência de regras (passos) a serem executadas sobre essa entrada, e uma saída. Nesta seção aprenderemos como lidar com a entrada de programas Python.

Na prática, um programa de computador pode receber sua entrada de muitas formas: por meio do teclado (quando o usuário digita alguma coisa), via linha de comando, por meio de arquivos de entrada, ou até mesmo por meio de cliques do usuário em certos botões ou áreas da tela do computador. Nesta seção aprenderemos como ler a entrada a partir do teclado, de arquivos, e da linha de comando.

Leitura de Dados do Teclado

Em python, para ler dados digitados pelo usuário durante a execução do programa, utilizamos a função input() (literalmente entrada, em inglês). O exemplo abaixo ilustra o uso dessa função:

print("Digite seu nome:")
nome = input()
print("Bem-vindo, ", nome)
Digite seu nome:
Algoritmos em Python
Bem-vindo,  Algoritmos em Pyhon

Um detalhe importante a ser lembrado é que a função input() sempre lê strings. Por isso, caso você deseje ler um número, deverá converter o dado retornado por essa função para o formato numérico apropriado.

Outra opção (mais eficiente) para leitura de dados é usar a função readline(). Suponha que queiramos ler dois números inteiros, representando a idade e o peso (arredondado) de uma pessoa. Um exemplo desse tipo de dado seria o seguinte:

45 70

Para ler esses dois valores (como inteiros) em Python, podemos fazer o seguinte:

import sys

idade, peso = map(int, sys.stdin.readline().split())

Esse tipo de leitura de dados é bastante útil quando estamos lidando com dados que obedecem um formato específico. No código acima, o que fazemos é mapear cada um dos elementos lidos para o tipo int.

Leitura de Dados de Arquivos

É possível também ler dados diretamente de um arquivo em Python. Por exemplo, considere que tenhamos um arquivo de texto chamado arquivo.txt em nosso computador (no mesmo diretório que nosso programa Python) com o seguinte conteúdo:

Sujeito de sorte (Belchior):
Presentemente eu posso me considerar um sujeito de sorte
Porque apesar de muito moço me sinto são e salvo e forte
E tenho comigo pensado Deus é brasileiro e anda do meu lado
E assim já não posso sofrer no ano passado

Agora desejamos ler e imprimir o conteúdo deste arquivo. Como podemos fazer isso? Uma opção é fazer como mostrado abaixo:

arquivo = open('arquivo.txt', 'r') (1)
conteudo = arquivo.read() (2)
print(conteudo)
Sujeito de sorte (Belchior):
Presentemente eu posso me considerar um sujeito de sorte
Porque apesar de muito moço me sinto são e salvo e forte
E tenho comigo pensado Deus é brasileiro e anda do meu lado
E assim já não posso sofrer no ano passado
1 Usamos a função open() para abrir o arquivo chamado arquivo.txt. Além disso, passamos como argumento para a função open() o caminho do arquivo no nosso computador (como o arquivo estava no mesmo diretório do programa que o lê, passamos somente o nome do arquivo). Passamos também a opção r para a função open(), que indica que o arquivo deverá ser aberto para leitura (read, em inglês). Isso quer dizer que dentro do nosso programa, não poderemos escrever nada em arquivo.txt, somente ler.
2 Usamos a função read() para ler o conteúdo do arquivo aberto e armazená-lo na variável conteudo.

Um problema que pode acontecer é o arquivo de entrada ser muito grande (maior que a memória do computador). Nesse caso, seria necessário ler o arquivo aos poucos. Python nos permite fazer isso por meio da função readlines() ("lê linhas", em inglês), que, como o próprio nome indica, lê o arquivo uma linha de cada vez. Vejamos um exemplo:

arquivo = open('arquivo.txt', 'r')
for linha in arquivo.readlines():
    print(linha)
Sujeito de sorte (Belchior):

Presentemente eu posso me considerar um sujeito de sorte

Porque apesar de muito moço me sinto são e salvo e forte

E tenho comigo pensado Deus é brasileiro e anda do meu lado

E assim já não posso sofrer no ano passado

Perceba que o resultado é quase que o mesmo do exemplo anterior, com a exceção que temos linhas em branco adicionais. Isso ocorre porque a função print() automaticamente insere quebras de linha depois de imprimir algo. Para suprimir este efeito, poderíamos ter invocado essa função como print(linha, end=''), que indicaria que uma string vazia (e não uma quebra de linha) deveria ser inserida ao final da impressão de cada linha do arquivo. Tirando isso, temos o mesmo resultado da função read() e com o benefício de ler o arquivo aos poucos, o que é vantajoso em caso de arquivos muito grandes.

Redirecionamento de Entrada e Saída

É possível ainda fazer com que um programa interprete dados vindos de um arquivos como se eles estivessem vindo do teclado. Para isso, é preciso usar o recurso de redirecionamento de entrada nos sistemas operacionais. Esse redirecionamento é feito no prompt de comandos (ou terminal, no Linux) por meio do operador <.

Tanto no Windows quanto no Linux e no Mac OS, dado um arquivo de entrada entrada.txt e um programa prog.py, podemos fazer o programa interpretar o conteúdo desse arquivo como se estivesse vindo da entrada padrão (teclado) com o seguinte comando:

prog.py < entrada.txt

Analogamente, podemos redirecionar a saída de um programa Python para um arquivo. Para isso, basta usarmos o sinal de redirecionamento >. Por exemplo, para redirecionar a saída da execução de um programa prog.py para um arquivo saida.txt, basta executarmos:

prog.py > saida.txt

Podemos também fazer as duas coisas (ler de um arquivo e escrever em outro) simultâneamente:

prog.py < entrada.txt > saida.txt

É possível ainda ler a saída do seu programa no terminal e redirecioná-la para um arquivo ao mesmo tempo. Para isso, usamos a ferramenta de linha de comando chamada tee, como mostrado abaixo:

prog.py < entrada.txt | tee saida.txt
O utilitário tee está presente no Linux, mas não está presente no Windows, por padrão. Se você estiver usando Windows, e quiser usar esse utilitário, precisará instalá-lo antes.

Leitura de Dados da Linha de Comando

A forma mais comum de execução de programas Python é a partir da linha de comando. Para executar um arquivo Python na linha de comando, basta digitar:

python programa.py

No exemplo acima, programa.py é o nome do arquivo onde o código do nosso programa Python está armazenado.

Além da execução de programas, também é possível passarmos argumentos para um programa via linha de comando. Por exemplo, suponha que tenhamos um arquivo chamado ola-mundo.py com o programa abaixo:

print("Olá, mundo!")

Se digitarmos python ola-mundo.py na linha de comando, obteremos a seguinte mensagem:

Olá, mundo!

Agora, suponha que em vez de imprimir "Olá, mundo!", a gente queira imprimir uma mensagem de boas vindas direcionada à pessoa que está executando o programa. Para isso, podemos obter o nome da pessoa via linha de comando e então exibir a mensagem de boas vindas.

Em Python, podemos capturar argumentos da linha de comando usando o módulo sys. O exemplo abaixo ilustra o uso desse módulo em nosso programa.

import sys (1)
nome = sys.argv[1] (2)
print("Olá, ", nome)
1 Nesta linha, estamos importando o módulo Python chamado sys. Ao fazer isso, todas as funções e recursos disponíveis nesse módulo.
2 Nesta linha, estamos atribuindo à variável nome o valor do segundo elemento da lista sys.argv. Essa lista armazena os argumentos passados via linha de comando para o interpretador Python (responsável por executar nosso programa). O primeiro elemento dessa lista (sys.argv[0]) é o nome do programa sendo executado (ola-mundo.py, em nosso exemplo), e as demais posições armazenam os demais argumentos passados na linha de comando. Explicaremos o uso da lista sys.argv em mais detalhes abaixo.

Agora, podemos executar o programa assim: python ola-mundo.py Maria. Como resultado, o programa irá imprimir a seguinte mensagem:

Olá, Maria

Manipulando a lista sys.argv

Como dissemos acima, a lista sys.argv armazena os argumentos passados para o intepretador Python ao invocar um programa. Essa lista é construída de modo que:

  • sys.argv[0] armazena o nome do programa sendo executado.

  • sys.argv[1] armazena o primeiro argumento (parâmetro) passado para o programa sendo executado.

  • sys.argv[2] armazena o segundo argumento (parâmetro) passado para o programa sendo executado.

  • …​ e assim por diante.

Assim como qualquer lista em Python, podemos obter o tamanho da lista, imprimi-la, percorrê-la, etc. No exemplo abaixo, imprimimos o número de argumentos passados para o programa e a seguir imprimimos cada um desses argumentos.

import sys

print("Número de argumentos: ", len(sys.argv) - 1) (1)

for arg in sys.argv:
  print(arg)

Se invocarmos um programa chamado prog.py com o comando python prog.py arg1 arg2 arg3 arg4, obteremos a seguinte saída:

Número de argumentos: 4
prog.py
arg1
arg2
arg3
arg4
1 Como mencionamos anteriormente, o primeiro elemento da lista sys.argv é o nome do arquivo (programa) sendo executado. Isso tem algumas implicações. Primeiro, se invocarmos o programa via linha de comando, essa lista nunca será vazia, pois ela terá pelo menos o elemento em sys.argv[0] que, como dissemos, é o nome do programa sendo executado. Segundo, se quisermos obter o número de argumentos passados para o nosso programa, precisamos subtrair 1 do tamanho da lista, como fizemos no exemplo acima.
Estritamente falando, a lista sys.argv contém os argumentos passados para o interpretador Python. Assim, quando executamos um programa usando python prog.py arg1 arg2, estamos passando os argumentos (parâmetros) prog.py, arg1 e arg2 para o interpretador Python. Portanto, a lista sys.argv será [prog.py, arg1, arg2]. Entretanto, ao invocar o interpretador Python usando argumentos adicionais, ele se encarregará de passar esses argumentos adiante para o programa a ser executado. Na verdade, o interpretador Python torna toda a lista sys.argv visível no programa que estamos executando.

Passagem de argumentos via linha de comando é um recurso muito útil, porém seu uso requer alguns cuidados.

Por exemplo, o que aconteceria se não passásemos o argumento Maria, ou seja, se executássemos o programa usando python ola-mundo.py, ao invés de python ola-mundo.py Maria?

Neste caso, a execução do programa seria abortada com um erro, pois não haveria nenhum elemento em sys.argv[1]. Felizmente, tratar este tipo de coisa é muito simples. No exemplo abaixo, verificamos o número de argumentos passados para o nosso programa e, caso este número não seja o esperado, imprimimos uma mensagem sobre como o programa deve ser utilizado e encerramos sua execução.

import sys

if len(sys.argv) < 2:
  print("Número incorreto de argumentos. Utilize: python prog.py nome-a-ser-impresso")
  sys.exit() # Encerra a execução do programa

nome = sys.argv[1]
print("Olá, ", nome)

E o que aconteceria se executássemos o programa usando python ola-mundo.py Maria Madalena, ao invés de python ola-mundo.py Maria?

O programa imprimiria somente Olá, Maria. Por quê?

A razão disso é que, por definição, os argumentos na linha de comando são separados por espaços. Assim, a palavra Madalena foi armazenada em sys.argv[2], e em nosso programa só lidamos com o valor em sys.argv[1]. Uma forma de contornar isso seria passar o nome Maria Madalena entre aspas, assim ele seria considerado como um único parâmetro em vez de dois. Outra opção seria imprimir não só o elemento em sys.argv[1], mas também os demais elementos desta lista.