45
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Python】ターミナル表示で色を付けたい。

Last updated at Posted at 2021-06-18

はじめに

Python で 「ターミナル表示で色を付けたいなぁ〜〜」と思った。

探索

調べたところ、たくさんのライブラリが出てきた。

  • print-color

  • colorprint

  • termcolor

うーん、どれもイマイチ。。。。

3-bit and 4-bit の一部しか対応してない。

8-bit color だったり、24-bit color (RGB) といったもっと細かく色指定ができるのに(蛇足になるかもしれないが)。

また、'gray' とか 'red' とか 文字列で指定しないといけないので、スペルミスが予想されたり、使える色を調べるのにソースレベルで見ないといけない。
 
とても不便。

なので、作った。

※後々分かったが、windowsだとctypesでwin32api呼んで、わちゃわちゃしないといけないので非対応(使える色が少ない。既にcoloramaというものがあった)

3-bit, 4-bit, 8-bit, 24-bit color フル対応

color-printer とか、print-color とか既に使われているから命名に困った。
term-printer にした。

使用方法

至って簡単。

まずは、pipでインストール。

$ pip install term-printer

1. 単純に全文色付け。

term_printer (モジュール名はアンスコ (_) なので要注意) から、Colorcprintをimportする。

あとは、cprintの引数にattrs=[]で使用したい色を指定。

attrs は必ず list でないといけないので注意。

from term_printer import Color, cprint

cprint("これは赤色になります。", attrs=[Color.RED])
cprint("これは明るい赤色になります。", attrs=[Color.BRIGHT_RED])
cprint("これは背景色が赤色になります。", attrs=[Color.BG_RED])
cprint("これは背景色が明るい赤色になります。", attrs=[Color.BG_BRIGHT_RED])

スクリーンショット 2021-06-17 0.21.35.png

ちゃんとしたエディタだと、写真のように補完されるのでスペルミスが起きることはない。
スクリーンショット 2021-06-17 0.21.15.png

Colorには、
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE の8色

  • フォントカラー (XXX)
  • 明るいフォントカラー (BRIGHT_XXX)
  • 背景カラー (BG_XXX)
  • 明るい背景カラー (BG_BRIGHT_XXX)

の4パターン、計32色 用意されている。

2 . フォーマットを変更してみる

次は、Format も import する。

太字にしたり、薄くしたり、斜体にしたり。

from term_printer import Color, Format, cprint

cprint("これは赤色になります。", attrs=[Color.RED])
cprint("これは赤色で太字になります。", attrs=[Color.RED, Format.BOLD])
cprint("これは赤色で薄くなります。", attrs=[Color.RED, Format.FAINT])
cprint("これは赤色で斜体になります。", attrs=[Color.RED, Format.ITALIC])

スクリーンショット 2021-06-17 0.05.31.png

Formatの指定はこんな感じ

プロパティ 説明
BOLD 太字
FAINT 薄字
ITALIC 斜体
UNDERLINE 下線
BLINK 点滅
FAST_BLINK 速い点滅
REVERSE 反転
CONCEAL 非表示
STRIKE 取消線

OSや使用しているターミナルによって、使えたり使えなかったりする。

3 . もっとこまかく色指定

ここからが他のライブラリにはできないこと。

8-bit の 256色を使用するときは、Color256 を import して使う。

第一引数は、0-255の間で指定。
範囲外の数字を渡すと Exception 吐くようにしている。

第二引数は、背景色にするかどうか。
背景色にしたい場合は、True を渡す。(デフォルトではFalse

cprint は内部でビルトイン関数の print を呼んでいるので、そのまま end= などの引数も問題なく使える。

from term_printer import Color256, cprint

for c in range(0, 256):
    cprint("{: ^4}".format(c), attrs=[Color256(c)], end="")
print()

for c in range(0, 256):
    cprint(" " * 4, attrs=[Color256(c, is_bg=True)], end="")
print()

結果はこんな感じ。
スクリーンショット 2021-06-17 0.31.53.png

4 . さらに細かく色を指定

24-bit, すなわち 16,777,216色を使用するとき (絶対こんなに使わないw) は、ColorRGB を import して使う。

引数はR, G, Bの順番、0-255の間で指定。こちらも範囲外の数字を渡すと Exception 吐くようにしている。

グラデーション表示してみよ。

from term_printer import ColorRGB, cprint

STEP = 8

for r in reversed(range(0, 256, STEP)):
    b = 255 - r
    for g in range(0, 256, STEP):
        cprint(" " * 4, attrs=[ColorRGB(r, g, b, is_bg=True)], end="")

わーお。
スクリーンショット 2021-06-17 1.25.16.png

普通に使うと。

from term_printer import ColorRGB, cprint

cprint("赤: 0, 緑: 0, 青: 0", attrs=[ColorRGB(0, 0, 0)])
cprint("赤: 255, 緑: 0, 青: 0", attrs=[ColorRGB(255, 0, 0)])
cprint("赤: 0, 緑: 255, 青: 0", attrs=[ColorRGB(0, 255, 0)])
cprint("赤: 0, 緑: 0, 青: 255", attrs=[ColorRGB(0, 0, 255)])
cprint("赤: 255, 緑: 255, 青: 255", attrs=[ColorRGB(255, 255, 255)])
cprint("赤: 255, 緑: 255, 青: 0", attrs=[ColorRGB(255, 255, 0)])
cprint("赤: 255, 緑: 0, 青: 255", attrs=[ColorRGB(255, 0, 255)])
cprint("赤: 0, 緑: 255, 青: 255", attrs=[ColorRGB(0, 255, 255)])

スクリーンショット 2021-06-17 0.48.46.png

5 . 一部の文字だけ変更

計算の答えとか、一部のみ色変更したいとき、StdText を import する。

from term_printer import Color, Format, StdText, cprint

cprint("1 + 1 =", StdText("2", Color.CYAN))
cprint(StdText("[success]", Color.GREEN), "completed !")
cprint(StdText("[failure]", Color.RED), "failed !")
cprint(StdText("[waring]", Color.YELLOW), "alert !")

cprint(f"This is {StdText('bold', Format.BOLD)} text !")

スクリーンショット 2021-06-17 0.57.31.png

6 . 既存のコードに導入

もう現在、使用しているコードに色を付けたい! や
cprint 書くのめんどくさい! って時に使えます。

たとえば、50%の確率プログラムがあったとき。
[成功][失敗] だけ色を付けたい。

from random import randint

for _ in range(10):
    if 50 > randint(0,99):
        print("[成功] 50未満の数字を引きました!")
    else:
        print("[失敗] 50以上の数字を引いたよ...")

スクリーンショット 2021-06-17 1.08.56.png

ただ、cprintprint にエイリアス張って、StdText 使うだけ。

from random import randint

from term_printer import Color, StdText
from term_printer import cprint as print

for _ in range(10):
    if 50 > randint(0, 99):
        print(StdText("[成功]", Color.GREEN), "50未満の数字を引きました!")
    else:
        print(StdText("[失敗]", Color.RED), "50以上の数字を引いたよ...")

スクリーンショット 2021-06-17 1.09.41.png

結局、cprint は内部でビルトイン関数の print を呼んでいるので(2回目)、既存コードを改修することなく使える。

おわりに

メンテ待ってます。
英語よわよわなのでおかしい英語あったり、不具合など見つけたら PR か issue ください。

45
34
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
45
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?