Curso de Python / Criar uma ferramenta de linha de comando com argparse

O módulo argparse define argumentos de linha de comando, conversões, valores padrão e opções permitidas, além de gerar ajuda e mensagens de uso. Separe a interpretação dos argumentos do cálculo para reaproveitar a lógica e verificar os erros de entrada.

Distinguir argumentos posicionais e opções

Uma interface de linha de comando, ou CLI, recebe valores pelo terminal. Argumentos posicionais são associados pela ordem na chamada; opções como --currency têm um nome explícito. Neste exemplo, os números são posicionais e a moeda é uma opção com valor.

nargs="+" exige um ou mais valores para amounts. O parâmetro type indica a função de conversão, e choices limita as alternativas aceitas. O parser guarda os resultados em um objeto Namespace. A documentação de argparse descreve esses componentes.

Argumentos podem aparecer no histórico do shell e na lista de processos. Não passe senhas ou tokens por uma opção só porque ela tem um nome próprio; use um mecanismo adequado de entrada e gestão de segredos. Ao ampliar uma ferramenta com caminhos contendo espaços, coloque cada caminho entre aspas para que o shell o transmita como um argumento.

Executar uma ferramenta completa de soma

Salve o código completo abaixo como sum_cli.py, em UTF-8, em uma pasta de prática. Selecione o ambiente virtual do projeto no terminal. A implementação usa apenas a biblioteca padrão.

import argparse

def nonnegative(text):
    try:
        value = int(text)
    except ValueError as error:
        raise argparse.ArgumentTypeError("expected an integer") from error
    if value < 0:
        raise argparse.ArgumentTypeError("expected a nonnegative amount")
    return value

def main():
    parser = argparse.ArgumentParser(description="Sum expense amounts")
    parser.add_argument("amounts", type=nonnegative, nargs="+")
    parser.add_argument("--currency", choices=["KRW", "USD"], default="KRW", help="Output unit label; no currency conversion")
    args = parser.parse_args()
    print(f"{sum(args.amounts):,} {args.currency}")

if __name__ == "__main__":
    main()

Execute python sum_cli.py 3500 8000 2500 nessa pasta. No macOS ou Ubuntu, fora de um ambiente virtual, use python3 se esse for o comando do seu interpretador. Resultado esperado:

14,000 KRW

A função nonnegative tenta converter cada texto com int. Se a conversão falhar, ela fornece uma mensagem por meio de ArgumentTypeError; se o valor for negativo, fornece outra mensagem. Assim, o cálculo só recebe os inteiros aceitos. Esse conversor não é um validador de formato monetário local: por exemplo, 3,50 não é um inteiro aceito.

main organiza a interface. O teste if __name__ == "__main__" chama a interface quando o arquivo é executado diretamente, mas permite importá-lo sem interpretar imediatamente os argumentos de outro programa. A aula de funções e valores de retorno ajuda a separar a lógica reutilizável do ponto de entrada.

Conferir ajuda, validação e código de saída

Execute os comandos separadamente e confira o resultado de cada um:

python sum_cli.py --help
python sum_cli.py 0 500 --currency KRW

A ajuda funciona mesmo sem fornecer quantias: deve mostrar a descrição, amounts, --currency e as alternativas KRW e USD. O texto original de ajuda permanece em inglês porque vem das strings do programa. A segunda chamada imprime 500 KRW; zero é uma entrada permitida.

Uma execução normal termina com código zero. A ajuda também termina com zero. Erros usuais de argumentos terminam com código 2, uma mensagem de uso e a causa da rejeição. O texto exato e sua formatação podem variar com a versão de Python, por isso confira a regra informada e o código de saída em vez de depender de uma captura idêntica.

  1. Execute python sum_cli.py 0 e confira 0 KRW.
  2. Execute python sum_cli.py -1. A mensagem deve indicar que é esperada uma quantia não negativa.
  3. Execute python sum_cli.py abc. A mensagem deve indicar que é esperado um inteiro.
  4. Execute sem quantias e depois experimente python sum_cli.py 8000 --currency EUR. A primeira chamada viola a exigência de pelo menos uma quantia; a segunda usa uma moeda fora de choices.
  5. Restaure a chamada com os três valores iniciais e confirme o total original.

Logo depois de cada execução, confira $LASTEXITCODE no PowerShell ou echo $? em um shell de macOS ou Ubuntu. No PowerShell, a variável registra o código do último programa nativo executado, conforme a documentação de variáveis automáticas.

Ampliar a interface sem mudar o significado dos dados

--currency escolhe apenas o rótulo da saída. A chamada python sum_cli.py 14000 --currency USD imprime 14,000 USD, sem converter won em dólares. Os valores de entrada já devem estar expressos na unidade escolhida. A vírgula da saída é o separador de milhares do formato usado, não uma vírgula decimal brasileira.

O conversor delega a sintaxe numérica a int; isso é diferente de exigir exclusivamente uma sequência de algarismos ASCII. Se a aplicação tiver regras mais restritas de formato ou um teto de valor, implemente-as deliberadamente no conversor e teste os limites. Não suponha que a opção de moeda valide a origem ou a escala dos números.

Quando houver operações diferentes, subparsers pode organizar subcomandos como init, add e list. Passe somente os valores necessários às funções de cálculo, em vez de torná-las dependentes de um Namespace. Assim, cada operação pode ter um contrato claro e continuar reutilizável em testes ou outras interfaces.