Como analisar argumentos de linha de comando em Python

Deseja executar scripts Python com argumentos de linha de comando? Aprenda a analisar argumentos de linha de comando usando os módulos sys, getopt e argparse em Python.

Em Python, quando você quiser ler a entrada do usuário, você usará a função input(). No entanto, para alguns aplicativos, você pode querer passar certos argumentos enquanto executa o script na linha de comando.

Neste tutorial, aprenderemos como executar um script Python com opções e argumentos na linha de comando. Em seguida, aprenderemos como usar os módulos integrados do Python para analisar essas opções e argumentos.

Vamos começar!

Entendendo sys.argv em Python

Se você programou em C, sabe que uma das maneiras mais simples de passar argumentos para o programa é através da linha de comando. Para fazer isso, você pode estruturar a função principal da seguinte forma:

#include<stdio.h>

int main(int argc, char **argv){
    //argc: argument count
    //argv: argument vector
    
    //do something on the args

    return 0;
}

Aqui, argc significa contagem de argumentos e argv significa vetor de argumentos.

Executando scripts Python com argumentos de linha de comando

Em Python, você pode executar o script Python na linha de comando usando python3 filename.py. Ao fazer isso, você também pode passar um número arbitrário de argumentos de linha de comando:

$ python3 filename.py arg1 arg2 ... argn

O módulo sys fornece suporte pronto para uso para acessar e processar esses argumentos de linha de comando. sys.argv é a lista de todos os argumentos de linha de comando que passamos quando executamos o script Python.

Aqui está um exemplo onde executamos main.py com argumentos de linha de comando:

$ python3 main.py hello world python script

Podemos percorrer o vetor de argumento usando um loop for simples e a função enumerate:

# main.py

import sys

for idx, arg in enumerate(sys.argv):
    print(f"arg{idx}: {arg}")
# Output
arg0:main.py
arg1:hello
arg2:world
arg3:python
arg4:script

Vemos que o primeiro argumento (no índice 0) é o nome do arquivo Python. E os argumentos subsequentes começam no índice 1.

Este é um programa de trabalho mínimo que aceita e processa argumentos de linha de comando. No entanto, vemos alguns problemas:

  • Como os usuários do programa sabem quais argumentos passar?
  • E o que esses argumentos representam?

Isso não está muito claro. Para resolver isso, você pode usar os módulos getopt ou argparse. E aprenderemos isso nas próximas seções.✅

Análise de argumento de linha de comando usando getopt do Python

Vamos aprender como analisar argumentos de linha de comando usando o módulo integrado getopt.

  Qual é melhor para crescer seu negócio de comércio eletrônico?

Depois de importar getopt do módulo getopt, você pode especificar os argumentos a serem analisados ​​e as opções curtas e longas com as quais executar o script. Precisamos analisar todos os argumentos começando no índice 1 em sys.argv. Portanto, a fatia a ser analisada é sys.argv[1:].

Aqui, precisaremos de uma string de mensagem e um nome de arquivo. Vamos usar m e f como opções curtas e mensagem e arquivo como opções longas.

Mas como garantimos que uma opção específica requer um argumento?

  • Em opções curtas, você pode fazer com que uma opção exija um argumento adicionando dois pontos (:) após o nome curto da opção.
  • Da mesma forma, em opções longas, você pode adicionar um sinal = após a opção longa. Podemos capturar essas opções e seus respectivos argumentos.

Adicionando-os, teremos o seguinte código em main.py:

# main.py

import sys
from getopt import getopt

opts, args = getopt(sys.argv[1:],'m:f:',['message=","file="])

print(opts)
print(args)

Aqui, a variável opts contém as opções e argumentos como uma lista de tuplas. Qualquer outro argumento posicional que passarmos será coletado na variável args.

Podemos passar a mensagem e o nome do arquivo para executar o script e podemos usar as opções curtas ou longas.

Executando main.py usando as opções long, temos:

$ python3 main.py --message hello --file somefile.txt

Temos as opções e argumentos como tuplas na variável opts. Como não passamos nenhum argumento posicional, args é uma lista vazia.

# Output
[("--message', 'hello'), ('--file', 'somefile.txt')]
[]

De forma equivalente, também podemos usar as opções curtas conforme mostrado:

$ python3 main.py -m hello -f somefile.txt
# Output
[('-m', 'hello'), ('-f', 'somefile.txt')]
[]

⚠️ A opção curta -m neste exemplo não deve ser confundida com o sinalizador de linha de comando -m que é usado para executar um módulo como o módulo principal ao executar um script Python.

Por exemplo, você usará python3 -m unittest main.py para executar unittest como o módulo principal ao executar main.py.

Mencionamos que todos os outros argumentos posicionais que passamos serão coletados na variável args. Aqui está um exemplo:

$ python3 main.py -m hello -f somefile.txt another_argument

A lista args contém o argumento posicional another_argument.

# Output
[('-m', 'hello'), ('-f', 'somefile.txt')]
['another_argument']

Aqui, opts é uma lista de tuplas. Assim, podemos percorrê-lo, descompactar a tupla e extrair os argumentos correspondentes às opções específicas.

Mas o que fazemos com o nome do arquivo e a mensagem depois de processarmos esses argumentos? Abriremos o arquivo no modo de gravação e gravaremos a string da mensagem convertida em maiúsculas no arquivo.

# main.py
import sys
from getopt import getopt

opts, args = getopt(sys.argv[1:],'m:f:',['message=","file="])

print(opts)
print(args)

for option, argument in opts:
    if option == "-m':
        message = argument
    if option == '-f':
        file = argument

with open(file,'w') as f:
    f.write(message.upper())

Vamos executar main.py com as opções curtas e argumentos de linha de comando.

$ python main.py -m hello -f thisfile.txt
[('-m', 'hello'), ('-f', 'thisfile.txt')]
[]

Depois de executar main.py, podemos ver ‘thisfile.txt’ em nosso diretório de trabalho. Ele contém a string ‘hello’ convertida em letras maiúsculas (‘HELLO’).

$ ls
main.py  thisfile.txt
$ cat thisfile.txt
HELLO

Como analisar argumentos de linha de comando com Argparse

O módulo argparse, também incorporado à biblioteca padrão do Python, fornece funcionalidade para analisar argumentos de linha de comando e também construir interfaces de linha de comando.

  Como criar um site gratuito com nome de domínio personalizado, hospedagem e criptografia SSL?

Para analisar argumentos de linha de comando, vamos importar a classe ArgumentParser do módulo argparse. Aqui, instanciamos arg_parser, um objeto ArgumentParser:

from argparse import ArgumentParser

arg_parser = ArgumentParser()

Em seguida, gostaríamos de adicionar dois argumentos de linha de comando:

  • message: a string da mensagem, e
  • arquivo: o nome do arquivo com o qual gostaríamos de trabalhar.

Agora chamamos o método add_argument() em arg_parser para adicionar esses dois argumentos. Na chamada do método add_argument(), você pode definir help como uma string (uma descrição do argumento).

arg_parser.add_argument('message',help='message string')
arg_parser.add_argument('file',help='filename')

Até agora, instanciamos arg_parser e adicionamos os argumentos de linha de comando. Quando o programa é executado na linha de comando, você pode usar o método parse_args() em arg_parser para obter os valores dos argumentos.

Aqui, capturamos o namespace do argumento na variável args. Portanto, você pode usar args.argument_name para obter os valores dos argumentos.

Depois de obter os valores dos argumentos, escrevemos a string da mensagem com maiúsculas e minúsculas trocadas (usando o método de string swapcase()) no arquivo.

args = arg_parser.parse_args()

message = args.message
file = args.file

with open(file,'w') as f:
     f.write(message.swapcase())

Juntando tudo, aqui está nosso arquivo main.py:

# main.py

from argparse import ArgumentParser

arg_parser = ArgumentParser()
arg_parser.add_argument('message',help='message string')
arg_parser.add_argument('file',help='filename')

args = arg_parser.parse_args()
print(args)

message = args.message
file = args.file

with open(file,'w') as f:
     f.write(message.swapcase())

Compreendendo o uso de argumentos de linha de comando

Para entender o uso dos argumentos ao executar main.py, você pode usar a opção –help long conforme mostrado:

$ python3 main.py --help
usage: main.py [-h] message file

positional arguments:
  message     message string
  file        filename

optional arguments:
  -h, --help  show this help message and exit

Não há argumentos opcionais e tanto a mensagem quanto o arquivo são argumentos posicionais obrigatórios. Como alternativa, você também pode usar a opção curta -h:

$ python3 main.py -h
usage: main.py [-h] message file

positional arguments:
  message     message string
  file        filename

optional arguments:
  -h, --help  show this help message and exit

Como visto, ambos os argumentos são argumentos posicionais por padrão. Portanto, se você não passar um ou mais desses argumentos, incorrerá em erros.

Aqui, passamos um argumento posicional (Hello) para a string da mensagem, mas não fornecemos nenhum valor para o argumento do arquivo.

E obtemos um erro informando que o argumento do arquivo é necessário.

$ python3 main.py Hello
usage: main.py [-h] message file
main.py: error: the following arguments are required: file

Quando executamos main.py com ambos os argumentos posicionais, vemos que o namespace args contém os valores dos argumentos.

$ python3 main.py Hello file1.txt
# Output
Namespace(file="file1.txt", message="Hello")

Agora, se examinarmos o conteúdo do diretório de trabalho atual, veremos que o script cria o arquivo ‘file1.txt’:

$ ls
file1.txt  main.py

A string da mensagem original é ‘Hello’; depois de trocar o caso, a string da mensagem no arquivo ‘file1.txt’ é ‘hELLO’.

$ cat file1.txt
hELLO

Como tornar opcionais os argumentos da linha de comando

Para tornar esses argumentos de linha de comando opcionais, você pode prefixar o nome do argumento com –.

  Como controlar seu Xbox One com o Google Assistente

Vamos modificar main.py para tornar a mensagem e os argumentos do arquivo opcionais.

# main.py

from argparse import ArgumentParser

arg_parser = ArgumentParser()
arg_parser.add_argument('--message',help='message string')
arg_parser.add_argument('--file',help='filename')

Como os argumentos da linha de comando são opcionais, podemos definir valores padrão para esses argumentos.

if args.message and args.file:
    message = args.message
    file = args.file
else:
    message="Python3"
    file="myfile.txt"

Neste ponto, o arquivo main.py contém o seguinte código:

# main.py

from argparse import ArgumentParser

arg_parser = ArgumentParser()
arg_parser.add_argument('--message',help='message string')
arg_parser.add_argument('--file',help='filename')

args = arg_parser.parse_args()
print(args)

if args.message and args.file:
    message = args.message
    file = args.file
else:
    message="Python3"
    file="myfile.txt"

with open(file,'w') as f:
     f.write(message.swapcase())

Se verificarmos o uso, veremos que tanto a mensagem quanto o arquivo são argumentos opcionais. O que significa que agora você pode executar main.py sem esses dois argumentos.

$ python3 main.py --help
usage: main.py [-h] [--message MESSAGE] [--file FILE]

optional arguments:
  -h, --help         show this help message and exit
  --message MESSAGE  message string
  --file FILE        filename
$ python3 main.py

No namespace do argumento, o arquivo e a mensagem são Nenhum.

# Output
Namespace(file=None, message=None)

Vemos que o nome de arquivo padrão e a mensagem ‘myfile.txt’ e ‘Python3’ são usados. O arquivo ‘myfile.txt’ agora está no diretório de trabalho:

$ ls
file1.txt  main.py  myfile.txt

E contém a string ‘Python3’ com o caso das letras trocadas:

$ cat myfile.txt
pYTHON3

Você também pode usar os argumentos –message e –file para tornar o comando mais legível.

$ python3 main.py --message Coding --file file2.txt
# Output
Namespace(file="file2.txt", message="Coding")

Vemos o ‘file2.txt’ no diretório de trabalho:

$ ls
file1.txt  file2.txt  main.py  myfile.txt

E contém a string ‘cODING’ como esperado.

$ cat file2.txt
cODING

Conclusão

Aqui está um resumo do que aprendemos neste tutorial:

  • Semelhante à linguagem de programação C, em Python, você pode acessar os argumentos da linha de comando percorrendo o vetor de argumento sys.argv. sys.argv[0] é o nome do script Python. Portanto, estamos interessados ​​em analisar os argumentos sys.argv[1:].
  • No entanto, para melhorar a legibilidade e poder adicionar opções, você pode usar os módulos getopt e argparse.
  • Você pode usar o módulo getopt para analisar a lista de argumentos de linha de comando começando no índice 1 até o final da lista. Você pode especificar opções curtas e opções longas.
  • Quando uma opção aceita um argumento, você pode especificar dois pontos (:) e = após a opção curta e a opção longa, respectivamente.
  • Com o módulo argparse do Python, você pode instanciar um objeto ArgumentParser e usar o método add_argument() para adicionar um argumento posicional necessário. Use — antes do nome do argumento para torná-lo opcional.
  • Para recuperar os valores dos argumentos da linha de comando, chame o método parse_args() no objeto ArgumentParser.

Em seguida, aprenda como executar hashing seguro em Python.