SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

Python 3.0開発者ガイド:数値、文字列、データ

数値、文字列、バイナリデータの基本データ型の処理

  • X ポスト
  • このエントリーをはてなブックマークに追加

エスケープシーケンスの使用

 エスケープシーケンスは、ESC+[で始めます(制御シーケンス開始とも言います)。ESC文字は出力不能で、chr(27)または\x1b(16進表記)でも指定できます。033は27の8進表記です。\033[の次の31mは、テキストの色を赤に変更するコードです。次に対象テキスト(Red Text)が続き、最後にテキストの色をデフォルトに戻すコード(\033[0m)を指定します。Pythonの方では8進表記が0(number}から0O{number}に変更になりましたが、ANSIエスケープシーケンスは今も0{number}表記を使用する端末に対応しています。

 エスケープシーケンスはさまざまな操作に使用でき、文字色や背景色の変更、画面上のカーソルの移動(特定の場所への出力)、画面の特定部分の消去、カーソルの表示/非表示、スクリーンバッファのスクロールなどができます。ここでは色の変更の例のみ説明します。

 ある小さなモジュールに、文字列、文字色、背景色の3つの引数を受け取り、該当するANSIエスケープシーケンスで文字列を囲むcolorize()という関数を作成するとします。まず、文字列からANSIエスケープコードにマップされたすべての文字色と背景色を含む、小さなグローバルディクショナリを用意します。関数自体では、文字色と背景色またはその一方がredやgreenのような名前で指定されているかどうかを検査し、ディクショナリから対応するコードを見つけ、指定の色に変更する適切なエスケープシーケンスを用意します。最後にすべてを通常の設定に戻します。ここに示すコードにはエラー処理がないので、指定の色がない場合にはKeyError例外が発生します。

colors = ['black', 'red', 'green', 'orange', 'blue', 'magenta', 'cyan', 'white']
color_dict = {}
for i, c in enumerate(colors):
  color_dict[c] = (i + 30, i + 40)

def colorize(text, color=None, bgcolor=None):
  c = None
  bg = None
  if color is not None:
  c = color_dict[color][0]
  if bgcolor is not None:
    bg = color_dict[bgcolor][1]

  s = ''
  if c is not None:
    s = '\033[%dm' % c
  if bg is not None:
    s += '\033[%dm' % bg
  return '%s%s\033[0m' % (s, text)

 このコードを使って、さまざまな文字色と背景色の出力を試すことができます。以下は、白のテキストとマゼンタの背景を出力する例です。

print(colorize('White on Magenta', 'white', 'magenta'))

 このコードとcolorizeモジュールは、Python 2.xと3.0のどちらでも動作します。

 colorize()関数を習得すれば、それ自体の色を書式指定するColorStringクラスも作成できます。その基本的な方法は、組み込みのstrクラスからサブクラスを作成し、__format__()メソッドを追加し、このメソッドが受け取るformat_specを文字色としてcolorize()関数に渡し、その関数から囲まれた文字列を返す、というものです。

class ColorString(str):
  def __format__(self, format_spec):
    s = colorize(self, format_spec)
    return s

 この実装では、背景色は変更できず、文字色の変更だけですが、書式指定が非常に簡潔になります(色名を指定するだけです)。以下は、ColorStringの使用例です。この例では、まず、1つの文「'Yeah, it works!'」を分割してColorStringの単語のリストを用意し、次にred、green、blueという色の書式指定文字列を指定して、各単語をそれぞれ異なる色で出力します。

words = [ColorString(x) for x in 'Yeah, it works!'.split()]
print('{0:red} {1:green} {2:blue}'.format(*words))

 Python 3.0には、単一のオブジェクトの書式指定に使用するformat()グローバル関数もあります。これは単純にオブジェクトの__format__()メソッドを呼び出します。ColorStringの例では次のようになります。

>>> format(ColorString('Gigi'), 'red')
'\x1b[31mGigi\x1b[0m'

 このサブクラス化スキームは有効に機能しますが、カスタム書式指定を行うたびに、__format__()メソッドを持つ特別なクラスを作成するのは、少し面倒な気もします。また、このようなサブクラス化では、書式指定を利用する開発者がColorStringのような特別なオブジェクトを作成する必要が生じます。幸い、独自の書式指定クラスを実装してあらゆる型の書式指定に使用することもできます。例えば、単にテキストを指定の色で出力できれば便利です。以下はColorFormatterというクラスの例です。このクラスはstring.Formatterクラスのサブクラスで、format_fieldメソッドをオーバーライドします。このオーバーライドでは、colorsリスト内にformat_specがあればフィールドの色を変更し、なければFormatter.format_field()を呼び出してデフォルトの書式指定を適用します。

from string import Formatter

class ColorFormatter(Formatter):
  def format_field(self, value, format_spec):
    if format_spec in colors:
      return colorize(value, format_spec)
    else:
      return Formatter.format_field(self, value, format_spec)

 カスタム書式指定クラスを使用するには、それをインスタンス化し、format()メソッドを呼び出して書式指定された文字列を取得する必要があります。これをもっと簡潔にするために、バインドされたformat()メソッドをfという変数に割り当てると、さらに使いやすくなります。

formatter = ColorFormatter()
f = formatter.format

print(f('{0:cyan} works very {1:orange}.', 'ColorFormatter', 'well'))

 フィールド値のリストまたは名前付きフィールドのディクショナリがある場合には、vformat()メソッドを使用できます。このメソッドは、位置指定引数としてリストを、キーワード引数としてディクショナリを受け取ります。

formatter = ColorFormatter()
f = formatter.vformat

args = ['The', 'vformat()']
kwargs = dict(m='method', t='too')
print(f('{0:red} {1:blue} {m:green} works {t:magenta}', args, kwargs)

まとめ

 Windows開発者がPython 3.0を少し勉強したいという場合は、色のANSIエスケープコードをWindowsに実装する、新しい代替print()関数を作成してみるとよいでしょう。その代替print()関数では、出力するテキストをスキャンしてANSIエスケープシーケンスを探し、それを解析し、SetConsoleTextAttribute() APIを使用して該当する色設定を適用します。

 この記事では、さまざまな例を示して、Python 3.0の細かい変更点がデータ型、算術演算、文字列書式指定に及ぼす影響について説明しました。これ以外にも、Python 3.0では標準ライブラリに重要な変更が行われており、それについてはこのシリーズの次回の記事で説明します。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Gigi Sayfan(Gigi Sayfan)

 主に大規模分散システムを対象とした、C/C++/C#/Python/Javaによるクロスプラットフォームのオブジェクト指向プログラミングに精通。現在は、Numenta社で脳の働きを模した人工知能システムの開発に取り組んでいる。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4052 2009/06/29 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング