Utilizar linhas de comando em scripts Python é razoavelmente simples. O script abaixo funciona no Python 2.8 ou superior. Existem mais opções e alternativas para ler a linha de comando, mas vamos nos ater ao básico…
import argparse as args parser = args.ArgumentParser(description='Analyzing commandline...') parser.add_argument("-b", "--blockfile" , default="blocklist.txt" , required=False , help="File containing the sites that should be blocked. One site per line.") parsed_args = parser.parse_args() print(parsed_args.blockfile)
Explicando o fonte acima:
- Primeiro importamos a classe que processa as linhas de comando;
- Depois criamos um Parser para analisar a linha de comando. O atributo ‘description’ será exibido quando esta linha for processada;
- O próximo passo é adicionar os argumentos que você deseja receber no seu script;
- Os dois primeiros atributos são nome e flag do atributo. Qualquer um destes valores poderá ser utilizado na linha de comando;
- default é o valor padrão para este argumento, caso ele seja omitido;
- required define se o argumento é obrigatório ou não. Se ele for obrigatório, o atributo default não é utilizado;
- help é o texto que será exibido quando o script for executado com -h (ou –help);
- Uma vez que todos os argumentos forem declarados, basta utilizar o a função parse_args() para recuperar os valores informados na linha de comando. Esta função vai retornar uma variável com com todas os argumentos que você definiu.
Este seria o resultado do código acima, caso o script seja executado sem argumentos:
python demo.py blocklist.txt
Ao mudar o atributo required para true…
python demo.py usage: PyGuestWatcher.py [-h] -b BLOCKFILE PyGuestWatcher.py: error: the following arguments are required: -b/--blockfile
Executando o script passando a linha de comando com chamando o argumento pelo nome (-b) ou pela flag (–blockfile)…
python demo.py -b 'foo.bar' 'foo.bar'
python demo.py --blockfile 'foo.bar' 'foo.bar'
*Update: 13/09/2018*
Antes de começar com o update de conteúdo deste post, gostaria de acrescentar um breve contexto: O exemplo acima foi de um script que fiz para bloquear acessos a sites. Ele lê o arquivo blocklist.txt e adiciona os sites no arquivo host, apontando eles para localhost.
Ok. Vamos a atualização de conteúdo…
O exemplo anterior funciona bem, mas o argparse tem outras opções que podem ser uteis.
Vamos imaginar um novo script com uma nova linha de comando. A primeira coisa que você deve fazer é instanciar o parser:
# Instanciating commandline argument parser parser = args.ArgumentParser("Analyzing commandline...")
Agora vamos adicionar alguns argumentos com configurações diferentes. No final, mostro um resumo destas possibilidades de configuração.
Argumento obrigatório do tipo numérico
parser.add_argument("-i", "--number", required=True, dest="arg_num", type=int, help="This is a required numeric argument.")
No código acima existem dois parâmetros que não foram utilizados no exemplo anterior:
- dest: Indica qual o nome da variável que vai armazenar o valor deste argumento. Se não for informado, o valor é armazenado em uma variável com o nome do argumento. Neste caso, se eu não tivesse informado o parâmetro dest, o valor seria acessado por uma propriedade chamada ‘number’;
- type: Indica o tipo do valor do argumento. Isso quer dizer a variável arg_num vai possuir um valor numérico e não uma string (que é o padrão);
Argumento obrigatório do tipo string
parser.add_argument("-s", "--string", required=True, dest="arg_str", type=str, help="This is a required string argument.")
Similar ao argumento anterior, mas com o tipo (type) definido para string (str), que é o padrão.
Argumento opcional do tipo numérico
parser.add_argument("-oi", "--optional-number", required=False, dest="arg_opt_num", type=int, help="This is an optional numeric argument.")
Argumento opcional do tipo string
parser.add_argument("-oi2", "--optional-number2", required=False, dest="arg_opt_num2", help="This is an optional numeric argument without a type defined.")
Neste argumento eu falo que estou esperando um número, mas como o type não foi definido para int, então o valor dele será sempre uma string.
Outro argumento opcional do tipo string
parser.add_argument("-os", "--optional-string", required=False, dest="arg_opt_str", type=str, help="This is an optional string argument.")
Este argumento é opcional (required=False) e foi definido explicitamente como string (type=str)
Mais um argumento opcional do tipo string
parser.add_argument("-os2", "--optional-string2", required=False, dest="arg_opt_str2", action="store", type=str, help="This is an optional string argument with explicit store action defined.")
Este argumento é similar ao anterior, mas possui um parâmetro a mais, o action. Ele define o que será feito com o argumento informado. O valor padrão é ‘store‘, que simplesmente armazena o valor do argumento em uma variável.
Argumento do tipo flag (define valor para True)
parser.add_argument("-t", "--true", required=False, dest="arg_true", action="store_true", default=False, help="This is a flag argument. If informed, will be set to true, otherwise, will be false.")
O argumento acima possui uma action diferente, a store_true. Isso indica que se você utilizar esta flag, o valor armazenado na variável dest será True. O valor padrão para este argumento é (por razões obvias) False.
Por flag eu quero dizer que é um argumento que você utiliza apenas ele. Ao contrário de um argumento do tipo numérico (-i 42), você vai utilizar apenas o argumento em si (-t ou –true)
Argumento do tipo flag (define valor para False)
parser.add_argument("-f", "--false", required=False, dest="arg_false", action="store_false", default=True, help="This is a flag argument. If informed, will be set to false, otherwise, will be true.")
Este argumento é similar ao anterior, mas seus valores são invertidos: Por padrão, este argumento é considerado como True e se for informado, muda para False. Isso foi definido na action com valor store_false.
Argumento do tipo flag sem valor default definido
parser.add_argument("-n", "--no-default", required=False, dest="arg_flag", action="store_false", help="This is a flag argument. If informed, will be set to false. No default configured for this.")
O argumento acima não possui um valor padrão, mas seu action está definido como store_false, ou seja, se for omitido, a variável arg_flag vai ficara com valor True.
Isso demonstra que o argparse é esperto o suficiente para entender que, se você quer armazenar False na variável, caso o argumento seja utilizado, então esta mesma variável deve possuir o valor oposto (True) como padrão.
Argumento do tipo lista
parser.add_argument("-l", "--list", required=False, dest="arg_list", default=[], action="append", help="This is an optional list argument with default value defined.")
O argumento acima é do tipo lista, ou seja, você pode utiliza-lo varias vezes na linha de comando, pois todos os valores informados serão adicionados a variável. Este comportamento é definido pelo valor append, informado no parametro action.
Argumento do tipo lista (numérico)
parser.add_argument("-li", "--list-int", required=False, dest="arg_list_int", type=int, action="append", help="This is an optional list of numbers argument with no default value defined.")
Este argumento é similar ao anterior. A primeira diferença é que definido um tipo para os valores passados (type=int) e isso implica em dizer que a variável vai possuir uma lista de integers.
A outra diferença é que não definimos um valor padrão (default=[]) para este argumento, ou seja, se este argumento não for utilizado, a variável arg_list_int terá o valor None ao invés de uma lista vazia ([]).
Argumento do tipo lista de constantes
parser.add_argument("-lc1", "--list-const1", required=False, dest="arg_list_const", action="append_const", const="Flag 1", help="This is a flag that adds a constant value to a list.") parser.add_argument("-lc2", "--list-const2", required=False, dest="arg_list_const", action="append_const", const="Flag 2", help="This is a flag that adds another constant value to a list.")
Acima estão dois argumentos, mas eles fazem parte do mesmo processo. Ambos estão com a action definida para append_const e isso quer dizer que eles vão adicionar um valor pre-definido a variável, resultando em uma lista de valores padrões.
A diferença entre append e append_const é que o append vai adicionar o valor que o usuário informar para a lista, enquanto o append_const vai adicionar o valor que você definiu.
Para que esta action funcione corretamente, o parametro dest deve ser igual para todos os argumentos relevantes.
Argumento do tipo versão
parser.add_argument("-v", "--version", action="version", version="{} | ver {}".format(__file__, __version__), help="Argument that prints the current version of your application.")
Assim como o argumento que mostra o texto de ajuda (-h ou –help), um argumento com action definido para version vai sobrescrever os outros argumentos e exibir apenas a sua informação, ou seja, você não pode misturar o argumento do tipo versão com os outros na mesma linha de comando.
O que este tipo de argumento faz é padronizar uma forma de exibir a versão da sua aplicação. Quando utilizado, ele vai mostrar o texto definido no parametro version.
Resumindo os parametros da função add_argument
- Primeiro parametro (posicional) recebe o ‘apelido’ do argumento. (Exemplo: -v);
- Segundo parametro (posicional) recebe o nome completo do argumento. Se o parâmetro dest não for informado, este será o nome da variável que armazena o valor do argumento;
- required: Indica se o argumento é ou não obrigatório (True/False);
- dest: Indica o nome da variável que vai receber o valor do argumento;
- action: Indica qual ação será tomada no argumento. Os valores possíveis são:
- store: (padrão) armazena o valor do argumento na variável;
- store_true: Armazena True se o argumento for utilizado. Caso contrário, o valor será False;
- store_false: Armazena False se o argumento for utilizado. Caso contrário, o valor será True;
- append: Adiciona o valor do argumento a uma lista;
- append_const: Adiciona um valor pre-definido a um lista. Devem ser adicionados varios argumentos, um para cada valor que poderá ser adicionado a lista;
- version: Exibe a verão do aplicativo (definido no parametro chamado version);
- const: Utilizado apenas quando o action está definido como append_const. Neste caso, o valor definido neste parametro será adicionado a lista;
- default: Valor padrão do argumento, caso ele não seja informado pelo usuário;
- version: Utilizado apenas quando o action está definido para “version”. Neste caso, o valor informado neste parametro será exibido para o usuário;
Para facilitar, fiz um exemplo no Github onde você pode passar estes valores e ver o resultado no console. Ele vai apenas exibir o nome da variável passada via linha de comando, seu valor e o tipo do valor.
Espero ter ajudado!
Referência:
Latest posts by Breno RdV (see all)
- O que é Metaclass e como ela funciona. (#python #dev #metaclass) - janeiro 11, 2023
- Entenda a mágica dos Generators. (#python, #dev, #generator, #iterator) - dezembro 28, 2022
- Ordenando um DataFrame por múltiplas colunas. (#python #pandas #jupyter #dev #data) - agosto 3, 2022