Eu conheço o --verbose
ou -v
de várias ferramentas e gostaria de implementar isso em alguns de meus próprios scripts e ferramentas.
Pensei em colocar:
if verbose:
print ...
através do meu código-fonte, para que se um usuário passar a -v
opção, a variável verbose
será definida como True
e o texto será impresso.
Esta é a abordagem certa ou existe uma forma mais comum?
Adição: não estou pedindo uma maneira de implementar a análise de argumentos. Que eu sei como isso é feito. Estou interessado apenas na opção prolixa.
Respostas:
Minha sugestão é usar uma função. Mas em vez de colocar o
if
na função, o que você pode ficar tentado a fazer, faça assim:(Sim, você pode definir uma função em uma
if
instrução, e ela só será definida se a condição for verdadeira!)Se você estiver usando Python 3, onde
print
já existe uma função (ou se quiser usarprint
como uma função no uso de 2.xfrom __future__ import print_function
), é ainda mais simples:Dessa forma, a função é definida como não fazer nada se o modo detalhado estiver desativado (usando um lambda), em vez de testar constantemente o
verbose
sinalizador.Se o usuário pudesse alterar o modo de verbosidade durante a execução do seu programa, esta seria a abordagem errada (você precisaria do
if
na função), mas como você está configurando com um sinalizador de linha de comando, você só precisa tome a decisão uma vez.Você então usa, por exemplo,
verboseprint("look at all my verbosity!", object(), 3)
sempre que quiser imprimir uma mensagem "detalhada".fonte
print
função: Aceite muitos argumentos. Pode ser implementado comoprint(*args)
em 3.xe comofor arg in args: print arg,
em 2.x. A principal vantagem é que ele permite misturar strings e coisas de outros tipos em uma mensagem, semstr
chamadas / formatação e concatenações explícitas .print arg,
linha?def verboseprint(*args, **kwargs): print(*args, **kwargs)
Use o
logging
módulo:Todos estes vão automaticamente para
stderr
:Para obter mais informações, consulte Python Docs e os tutoriais .
fonte
Construindo e simplificando a resposta de @ kindall, aqui está o que eu normalmente uso:
Isso fornece o seguinte uso em todo o seu script:
E seu script pode ser chamado assim:
Algumas notas:
3
que define o limite superior para seu registro, mas eu aceito isso como um compromisso pela simplicidade.v_print
trabalhar em todo o seu programa, terá que fazer o lixo com o global. Não é divertido, mas eu desafio alguém a encontrar uma maneira melhor.fonte
-v
for usado. Em sua solução atual, tudo é despejado em stdout ao invés de stderr. E: você normalmente deseja retransmitir todos os erros para o usuário, não é?O que faço em meus scripts é verificar em tempo de execução se a opção 'verbose' está definida e, em seguida, definir meu nível de log para depuração. Se não estiver definido, eu o defino como info. Dessa forma, você não tem verificações 'if verbose' em todo o código.
fonte
Pode ser mais limpo se você tiver uma função, digamos chamada
vprint
, que verifica o sinalizador detalhado para você. Em seguida, basta chamar sua própriavprint
função em qualquer lugar que desejar verbosidade opcional.fonte
Roubei o código de registro do virtualenv para um projeto meu. Olhe nos
main()
devirtualenv.py
ver como ele é inicializado. O código é polvilhado comlogger.notify()
,logger.info()
,logger.warn()
, e similares. Que emita métodos realmente saída é determinado por se virtualenv foi invocada com-v
,-vv
,-vvv
, ou-q
.fonte
A solução de @ kindall não funciona com meu Python versão 3.5. @styles afirma corretamente em seu comentário que o motivo é o argumento adicional de palavras-chave opcionais . Portanto, minha versão ligeiramente aprimorada para Python 3 se parece com isto:
fonte
Pode haver uma variável global, provavelmente definida com
argparse
fromsys.argv
, que indica se o programa deve ser detalhado ou não. Em seguida, um decorador poderia ser escrito de forma que, se a verbosidade estivesse ativada, a entrada padrão seria desviada para o dispositivo nulo, desde que a função fosse executada:Essa resposta é inspirada neste código ; na verdade, eu ia apenas usá-lo como um módulo em meu programa, mas recebi erros que não consegui entender, então adaptei uma parte dele.
A desvantagem dessa solução é que a verbosidade é binária, ao contrário de
logging
, que permite um ajuste mais preciso de quão detalhado o programa pode ser. Além disso, todas asprint
chamadas são desviadas, o que pode ser indesejado.fonte
O que eu preciso é uma função que imprima um objeto (obj), mas apenas se a variável global verbose for true, caso contrário, ela não fará nada.
Desejo ser capaz de alterar o parâmetro global "verbose" a qualquer momento. Simplicidade e legibilidade para mim são de suma importância. Então, eu procederia como as seguintes linhas indicam:
A variável global "verbose" também pode ser definida na lista de parâmetros.
fonte