Utilizando cores para escrever no terminal (Python)
Overview
Você já se perdeu em um mar de texto enquanto usava o terminal? Neste post leve e informativo, vamos mergulhar em como Python pode tornar suas mensagens de terminal não apenas informativas, mas também visualmente impactantes, graças ao uso de cores. Desde a abordagem simples com caracteres ANSI, passando pela utilização de pacotes como termcolor e sty, vamos explorar formas práticas e fáceis de melhorar a interação com os usuários dos seus scripts. Prepare-se para adicionar um toque de cor ao seu terminal!
Quem conhece Python sabe que uma das coisas que ele faz muito bem é automatizar tarefas. Durante estas automatizações, escrevemos mensagens no terminal, para que o usuário consiga acompanhar o que está acontecendo.
O problema começa quando escrevermos muitas coisas no terminal… fica aquele tanto de texto amontoado e só quem fez aquele script sabe identificar o que é importante ou não. Uma das formas de resolver isso é utilizar cores para destacar as mensagens importantes.Existem algumas formas de fazer isso. Vou começar pela que considero mais simples e que não depende de outros pacotes, depois vou mostrar como utilizar alguns pacotes mais famosos.
1. Utilizando caracteres ANSI
A primeira forma (e mais simples, na minha opinião) é utilizando caracteres ANSI. Esta forma consiste em colocar um conjunto de carecteres logo antes do texto que você quer colorir.
Veja a relação de códigos ANSI e suas respectivas cores:
RED = "\033[1;31m"
BLUE = "\033[1;34m"
CYAN = "\033[1;36m"
GREEN = "\033[0;32m"
RESET = "\033[0;0m"
BOLD = "\033[;1m"
REVERSE = "\033[;7m"
Agora um exemplo de como aplicar essas cores:
>>> print(RED + "ERROR!" + RESET + "Something went wrong...")
ERROR! Something went wrong...
Por que foi necessário concatenar o código RESET? Sem o reset (das cores), o resto da frase ficaria em vermelho.
Agora você pode se divertir a vontade e misturar as cores e estilos da forma que quiser, por exemplo:
>>> print(BOLD + RED + "ERROR!" + RESET + "Something went wrong...")
<strong>ERROR!</strong> Something went wrong...
Como pode ser observado, os caracteres referentes ao RESET removem todas as formatações.
OK. Então vimos que é só concatenar os valores… mas fica feio e pouco prático. Seria uma boa ideia encapsular esta lógica, certo? Podemos criar uma classe que resolve isso e (inclusive) implementa o que falamos no último post (Inicializando dicionário com valores padrões)…
A primeira coisa é criar a classe com um dicionário com um dicionário contendo a relação de cores:
class printer():
_colors_ = {
**dict.fromkeys(("RED", "ERROR", "NO"), "\033[1;31m"),
**dict.fromkeys(("GREEN", "OK", "YES"), "\033[0;32m"),
**dict.fromkeys(("YELLOW", "WARN", "MAYBE"), "\033[0;93m"),
"BLUE": "\033[1;34m",
"CYAN": "\033[1;36m",
"RESET": "\033[0;0m",
"BOLD": "\033[;1m",
"REVERSE": "\033[;7m"
}
O próximo passo é criar uma função que recebe o nome da cor e retorna o código ANSI correspondente:
def _get_color_(self, key):
"""Gets the corresponding color ANSI code... """
try:
return self._colors_[key]
except:
return self._colors_["RESET"]
A função acima tenta retornar o código correspondente ao argumento informado. Se não for possível, retorna o caractere que faz um reset nos formatos.
Agora é só criar a função que faz o print da mensagem:
def print(self, msg , color="RESET"):
"""Main print function..."""
# Get ANSI color code.
color = self._get_color_(key=color)
# Printing...
print("{}{}{}".format(color, msg, self._colors_["RESET"]))
A função acima recebe como argumento a mensagem e a cor. Se o nome da cor estiver errado, vai mostrar a mensagem sem a formatação.
Para utilizar é simples:
p = printer()
p.print(msg="SUCCESS Test...", color="GREEN")
p.print(msg="WARN Test...", color="YELLOW")
p.print(msg="ERRPR Test...", color="RED")
O fonte acima vai produzir o seguinte resultado:
SUCCESS Test...
WARN Test...
ERROR Test...
Para facilitar, criei esta classe e adicionei três métodos: success (verde), error (vermelho) e warning (amarelo). O fonte dela está no meu Github.
2. Utilizando o pacote termcolor
Para utilizar este pacote, a primeira coisa é baixa-lo. Para isso, utilize o PIP:
pip install termcolor
Este pacote é bem flexível e possui uma série de opções, mas vou utilizar um exemplo básico aqui:
from termcolor import colored
print(colored('Error Test!!!', 'red'))
print(colored('Warning Test!!!', 'yellow'))
print(colored('Success Test!!!', 'green'))
Disponibilizei este exemplo no meu Github. Existem mais exemplos na pagina deste pacote: https://pypi.python.org/pypi/termcolor
3. Utilizando o pacote sty
Assim como o termcolor, precisamos instalar este pacote. Sugiro utilizar o pip:
pip install sty
Este pacote tem mais possibilidades. Veja alguns exemplos de utilização abaixo:
from sty import fg, bg, ef, rs
print(fg.red + 'ERROR Test!' + fg.rs)
print(fg.li_yellow + 'WARNING Test!' + fg.rs)
print(fg.green + 'SUCCESS Test!' + fg.rs)
O resultado final é o mesmo dos exemplos anteriores. Inclui no meu Github um exemplo mais completo da utilização deste pacote. Link para o pacote: https://pypi.python.org/pypi/sty/1.0.0b4
Espero ter ajudado.