Pythonの技法:リスト以外の選択肢「関数の生成」

文:Nick Gibson(Builder AU)
翻訳校正:原井彰弘
2008/01/17 15:10

PythonによるHTMLのカラーコードの生成を例として用い、関数ファクトリについて解説する。

 すでにPythonでのリストの内包表記について記事を書いたが、その強力さに魅力を感じて、明示的なループを内包表記にリファクタリングしたいと思っている方々から、多くのフィードバックをいただいてた。

 ただし、何事においてもそうであるが、内包表記が役立つ場面がある一方で、ほかの書き方をした方がよい場面というのも存在する。そこで本稿では、内包表記ではなく関数ファクトリの使用がより適している例を取り上げて紹介する。

 本稿では、PythonによるHTMLのカラーコードの生成を例として用いる。HTMLでスムーズなグラデーションを作成する必要があり、エンコードの方式にそれほどこだわらないのであれば、テーブルを用いてbgcolor属性を変化させていくという手法を用いることによりとりあえずは作成できる。このケースでは、以下のようにしてリストの内包表記を用いるのがよいアプローチだろう。

def colourslist(red, green, blue, steps):

        def f((start,end), i, steps): 
                return start + i * (end-start)/float(steps)     

        colours = [tuple([f(c,i,steps-1) 
                        for c in [red,green,blue]]) 
                        for i in range(steps)]
        return ["%02x%02x%02x" % (rgb) for rgb in colours]

print "<html><body>"
print "<table cellspacing=0 cellpadding=0><tr>"
for colour in colourslist((90,90),(90,255),(90,90),200):
         print "<td width=1px bgcolor=%s> </td>" % (colour)
print "</tr></table>"
print "</body></html>"

 この例を実行すると、以下のように期待どおりの出力が行われる。

<table cellspacing=0 cellpadding=0><tr>
<td width=1px bgcolor=#5a5a5a>&nbsp;</td> <td width=1px bgcolor=#5a5a5a>&nbsp;</td> <td width=1px bgcolor=#5a5b5a>&nbsp;</td> <td width=1px bgcolor=#5a5c5a>&nbsp;</td> <td width=1px bgcolor=#5a5d5a>&nbsp;</td> <td width=1px bgcolor=#5a5e5a>&nbsp;</td> <td width=1px bgcolor=#5a5e5a>&nbsp;</td> <td width=1px bgcolor=#5a5f5a>&nbsp;</td> <td width=1px bgcolor=#5a605a>&nbsp;</td> <td width=1px bgcolor=#5a615a>&nbsp;</td> <td width=1px bgcolor=#5a625a>&nbsp;</td> <td width=1px bgcolor=#5a635a>&nbsp;</td> <td width=1px bgcolor=#5a635a>&nbsp;</td> <td width=1px bgcolor=#5a645a>&nbsp;</td> <td width=1px bgcolor=#5a655a>&nbsp;</td> <td width=1px bgcolor=#5a665a>&nbsp;</td> <td width=1px bgcolor=#5a675a>&nbsp;</td> <td width=1px bgcolor=#5a685a>&nbsp;</td> <td width=1px bgcolor=#5a685a>&nbsp;</td> <td width=1px bgcolor=#5a695a>&nbsp;</td> <td width=1px bgcolor=#5a6a5a>&nbsp;</td> <td width=1px bgcolor=#5a6b5a>&nbsp;</td> <td width=1px bgcolor=#5a6c5a>&nbsp;</td> <td width=1px bgcolor=#5a6d5a>&nbsp;</td> <td width=1px bgcolor=#5a6d5a>&nbsp;</td> <td width=1px bgcolor=#5a6e5a>&nbsp;</td> <td width=1px bgcolor=#5a6f5a>&nbsp;</td> <td width=1px bgcolor=#5a705a>&nbsp;</td> <td width=1px bgcolor=#5a715a>&nbsp;</td> <td width=1px bgcolor=#5a725a>&nbsp;</td> <td width=1px bgcolor=#5a725a>&nbsp;</td> <td width=1px bgcolor=#5a735a>&nbsp;</td> <td width=1px bgcolor=#5a745a>&nbsp;</td> <td width=1px bgcolor=#5a755a>&nbsp;</td> <td width=1px bgcolor=#5a765a>&nbsp;</td> <td width=1px bgcolor=#5a775a>&nbsp;</td> <td width=1px bgcolor=#5a775a>&nbsp;</td> <td width=1px bgcolor=#5a785a>&nbsp;</td> <td width=1px bgcolor=#5a795a>&nbsp;</td> <td width=1px bgcolor=#5a7a5a>&nbsp;</td> <td width=1px bgcolor=#5a7b5a>&nbsp;</td> <td width=1px bgcolor=#5a7b5a>&nbsp;</td> <td width=1px bgcolor=#5a7c5a>&nbsp;</td> <td width=1px bgcolor=#5a7d5a>&nbsp;</td> <td width=1px bgcolor=#5a7e5a>&nbsp;</td> <td width=1px bgcolor=#5a7f5a>&nbsp;</td> <td width=1px bgcolor=#5a805a>&nbsp;</td> <td width=1px bgcolor=#5a805a>&nbsp;</td> <td width=1px bgcolor=#5a815a>&nbsp;</td> <td width=1px bgcolor=#5a825a>&nbsp;</td> <td width=1px bgcolor=#5a835a>&nbsp;</td> <td width=1px bgcolor=#5a845a>&nbsp;</td> <td width=1px bgcolor=#5a855a>&nbsp;</td> <td width=1px bgcolor=#5a855a>&nbsp;</td> <td width=1px bgcolor=#5a865a>&nbsp;</td> <td width=1px bgcolor=#5a875a>&nbsp;</td> <td width=1px bgcolor=#5a885a>&nbsp;</td> <td width=1px bgcolor=#5a895a>&nbsp;</td> <td width=1px bgcolor=#5a8a5a>&nbsp;</td> <td width=1px bgcolor=#5a8a5a>&nbsp;</td> <td width=1px bgcolor=#5a8b5a>&nbsp;</td> <td width=1px bgcolor=#5a8c5a>&nbsp;</td> <td width=1px bgcolor=#5a8d5a>&nbsp;</td> <td width=1px bgcolor=#5a8e5a>&nbsp;</td> <td width=1px bgcolor=#5a8f5a>&nbsp;</td> <td width=1px bgcolor=#5a8f5a>&nbsp;</td> <td width=1px bgcolor=#5a905a>&nbsp;</td> <td width=1px bgcolor=#5a915a>&nbsp;</td> <td width=1px bgcolor=#5a925a>&nbsp;</td> <td width=1px bgcolor=#5a935a>&nbsp;</td> <td width=1px bgcolor=#5a945a>&nbsp;</td> <td width=1px bgcolor=#5a945a>&nbsp;</td> <td width=1px bgcolor=#5a955a>&nbsp;</td> <td width=1px bgcolor=#5a965a>&nbsp;</td> <td width=1px bgcolor=#5a975a>&nbsp;</td> <td width=1px bgcolor=#5a985a>&nbsp;</td> <td width=1px bgcolor=#5a995a>&nbsp;</td> <td width=1px bgcolor=#5a995a>&nbsp;</td> <td width=1px bgcolor=#5a9a5a>&nbsp;</td> <td width=1px bgcolor=#5a9b5a>&nbsp;</td> <td width=1px bgcolor=#5a9c5a>&nbsp;</td> <td width=1px bgcolor=#5a9d5a>&nbsp;</td> <td width=1px bgcolor=#5a9d5a>&nbsp;</td> <td width=1px bgcolor=#5a9e5a>&nbsp;</td> <td width=1px bgcolor=#5a9f5a>&nbsp;</td> <td width=1px bgcolor=#5aa05a>&nbsp;</td> <td width=1px bgcolor=#5aa15a>&nbsp;</td> <td width=1px bgcolor=#5aa25a>&nbsp;</td> <td width=1px bgcolor=#5aa25a>&nbsp;</td> <td width=1px bgcolor=#5aa35a>&nbsp;</td> <td width=1px bgcolor=#5aa45a>&nbsp;</td> <td width=1px bgcolor=#5aa55a>&nbsp;</td> <td width=1px bgcolor=#5aa65a>&nbsp;</td> <td width=1px bgcolor=#5aa75a>&nbsp;</td> <td width=1px bgcolor=#5aa75a>&nbsp;</td> <td width=1px bgcolor=#5aa85a>&nbsp;</td> <td width=1px bgcolor=#5aa95a>&nbsp;</td> <td width=1px bgcolor=#5aaa5a>&nbsp;</td> <td width=1px bgcolor=#5aab5a>&nbsp;</td> <td width=1px bgcolor=#5aac5a>&nbsp;</td> <td width=1px bgcolor=#5aac5a>&nbsp;</td> <td width=1px bgcolor=#5aad5a>&nbsp;</td> <td width=1px bgcolor=#5aae5a>&nbsp;</td> <td width=1px bgcolor=#5aaf5a>&nbsp;</td> <td width=1px bgcolor=#5ab05a>&nbsp;</td> <td width=1px bgcolor=#5ab15a>&nbsp;</td> <td width=1px bgcolor=#5ab15a>&nbsp;</td> <td width=1px bgcolor=#5ab25a>&nbsp;</td> <td width=1px bgcolor=#5ab35a>&nbsp;</td> <td width=1px bgcolor=#5ab45a>&nbsp;</td> <td width=1px bgcolor=#5ab55a>&nbsp;</td> <td width=1px bgcolor=#5ab65a>&nbsp;</td> <td width=1px bgcolor=#5ab65a>&nbsp;</td> <td width=1px bgcolor=#5ab75a>&nbsp;</td> <td width=1px bgcolor=#5ab85a>&nbsp;</td> <td width=1px bgcolor=#5ab95a>&nbsp;</td> <td width=1px bgcolor=#5aba5a>&nbsp;</td> <td width=1px bgcolor=#5abb5a>&nbsp;</td> <td width=1px bgcolor=#5abb5a>&nbsp;</td> <td width=1px bgcolor=#5abc5a>&nbsp;</td> <td width=1px bgcolor=#5abd5a>&nbsp;</td> <td width=1px bgcolor=#5abe5a>&nbsp;</td> <td width=1px bgcolor=#5abf5a>&nbsp;</td> <td width=1px bgcolor=#5abf5a>&nbsp;</td> <td width=1px bgcolor=#5ac05a>&nbsp;</td> <td width=1px bgcolor=#5ac15a>&nbsp;</td> <td width=1px bgcolor=#5ac25a>&nbsp;</td> <td width=1px bgcolor=#5ac35a>&nbsp;</td> <td width=1px bgcolor=#5ac45a>&nbsp;</td> <td width=1px bgcolor=#5ac45a>&nbsp;</td> <td width=1px bgcolor=#5ac55a>&nbsp;</td> <td width=1px bgcolor=#5ac65a>&nbsp;</td> <td width=1px bgcolor=#5ac75a>&nbsp;</td> <td width=1px bgcolor=#5ac85a>&nbsp;</td> <td width=1px bgcolor=#5ac95a>&nbsp;</td> <td width=1px bgcolor=#5ac95a>&nbsp;</td> <td width=1px bgcolor=#5aca5a>&nbsp;</td> <td width=1px bgcolor=#5acb5a>&nbsp;</td> <td width=1px bgcolor=#5acc5a>&nbsp;</td> <td width=1px bgcolor=#5acd5a>&nbsp;</td> <td width=1px bgcolor=#5ace5a>&nbsp;</td> <td width=1px bgcolor=#5ace5a>&nbsp;</td> <td width=1px bgcolor=#5acf5a>&nbsp;</td> <td width=1px bgcolor=#5ad05a>&nbsp;</td> <td width=1px bgcolor=#5ad15a>&nbsp;</td> <td width=1px bgcolor=#5ad25a>&nbsp;</td> <td width=1px bgcolor=#5ad35a>&nbsp;</td> <td width=1px bgcolor=#5ad35a>&nbsp;</td> <td width=1px bgcolor=#5ad45a>&nbsp;</td> <td width=1px bgcolor=#5ad55a>&nbsp;</td> <td width=1px bgcolor=#5ad65a>&nbsp;</td> <td width=1px bgcolor=#5ad75a>&nbsp;</td> <td width=1px bgcolor=#5ad85a>&nbsp;</td> <td width=1px bgcolor=#5ad85a>&nbsp;</td> <td width=1px bgcolor=#5ad95a>&nbsp;</td> <td width=1px bgcolor=#5ada5a>&nbsp;</td> <td width=1px bgcolor=#5adb5a>&nbsp;</td> <td width=1px bgcolor=#5adc5a>&nbsp;</td> <td width=1px bgcolor=#5add5a>&nbsp;</td> <td width=1px bgcolor=#5add5a>&nbsp;</td> <td width=1px bgcolor=#5ade5a>&nbsp;</td> <td width=1px bgcolor=#5adf5a>&nbsp;</td> <td width=1px bgcolor=#5ae05a>&nbsp;</td> <td width=1px bgcolor=#5ae15a>&nbsp;</td> <td width=1px bgcolor=#5ae15a>&nbsp;</td> <td width=1px bgcolor=#5ae25a>&nbsp;</td> <td width=1px bgcolor=#5ae35a>&nbsp;</td> <td width=1px bgcolor=#5ae45a>&nbsp;</td> <td width=1px bgcolor=#5ae55a>&nbsp;</td> <td width=1px bgcolor=#5ae65a>&nbsp;</td> <td width=1px bgcolor=#5ae65a>&nbsp;</td> <td width=1px bgcolor=#5ae75a>&nbsp;</td> <td width=1px bgcolor=#5ae85a>&nbsp;</td> <td width=1px bgcolor=#5ae95a>&nbsp;</td> <td width=1px bgcolor=#5aea5a>&nbsp;</td> <td width=1px bgcolor=#5aeb5a>&nbsp;</td> <td width=1px bgcolor=#5aeb5a>&nbsp;</td> <td width=1px bgcolor=#5aec5a>&nbsp;</td> <td width=1px bgcolor=#5aed5a>&nbsp;</td> <td width=1px bgcolor=#5aee5a>&nbsp;</td> <td width=1px bgcolor=#5aef5a>&nbsp;</td> <td width=1px bgcolor=#5af05a>&nbsp;</td> <td width=1px bgcolor=#5af05a>&nbsp;</td> <td width=1px bgcolor=#5af15a>&nbsp;</td> <td width=1px bgcolor=#5af25a>&nbsp;</td> <td width=1px bgcolor=#5af35a>&nbsp;</td> <td width=1px bgcolor=#5af45a>&nbsp;</td> <td width=1px bgcolor=#5af55a>&nbsp;</td> <td width=1px bgcolor=#5af55a>&nbsp;</td> <td width=1px bgcolor=#5af65a>&nbsp;</td> <td width=1px bgcolor=#5af75a>&nbsp;</td> <td width=1px bgcolor=#5af85a>&nbsp;</td> <td width=1px bgcolor=#5af95a>&nbsp;</td> <td width=1px bgcolor=#5afa5a>&nbsp;</td> <td width=1px bgcolor=#5afa5a>&nbsp;</td> <td width=1px bgcolor=#5afb5a>&nbsp;</td> <td width=1px bgcolor=#5afc5a>&nbsp;</td> <td width=1px bgcolor=#5afd5a>&nbsp;</td> <td width=1px bgcolor=#5afe5a>&nbsp;</td> <td width=1px bgcolor=#5aff5a>&nbsp;</td> </tr></table>

 Pythonプログラマの間では、デザインパターンに関する論争が時折生じる。他のオブジェクト指向言語からPythonの世界に入ってきた人には、デザインパターンなしでは生きていけないという人も多い。一方で、パターンを重要視しない言語からPythonの世界に入った人は、デザインパターンはすべてのプログラムがくぎに見える人のためのハンマーにすぎない、と考えている。しかし、いずれにしてもFactoryパターンはさまざまな問題を解決する上で役立つツールであるだろう。

記事の感想やご意見をコメントでお寄せください(CNET_IDログインが必要です)
ログイン パスワードを忘れた方  |  新規登録
米フォレスター・リサーチ社 シニアアナリスト Jeremiah K.Owyang氏を迎え、同氏が提唱するソーシャルテクノロジーを効果的に活用方法するための方法『POST』を日本で初めて紹介する注目のリアルイベント
  • 今日のトップ記事
  • 昨日
  • 2日前
  • 5日前
  • 6日前
  • 7日前
  • 新着記事
  • 人気記事
  • 特集
  • ブログ