忍者ブログ
     2008年11月14日 開始
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

http://www.python.jp/doc/release/tut/node13.html#SECTION0013400000000000000000

11.4 マルチスレッド処理
 

スレッド処理 (threading) とは、順序的な依存関係にない複数のタスクを分割するテクニックです。スレッド処理は、ユーザの入力を受け付けつつ、背後で別のタスクを動かすようなアプリケーションの応答性を高めます。主なユースケースには、 I/O を別のスレッドの計算処理と並列して動作させるというものがあります。

以下のコードでは、高水準のモジュール threading でメインのプログラムを動かしながら背後で別のタスクを動作させられるようにする方法を示しています:

 

    import threading, zipfile

    class AsyncZip(threading.Thread):
        def __init__(self, infile, outfile):
            threading.Thread.__init__(self)        
            self.infile = infile
            self.outfile = outfile
        def run(self):
            f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
            f.write(self.infile)
            f.close()
            print 'Finished background zip of: ', self.infile

    background = AsyncZip('mydata.txt', 'myarchive.zip')
    background.start()
    print 'The main program continues to run in foreground.'
    
    background.join()    # Wait for the background task to finish
    print 'Main program waited until background was done.'

マルチスレッドアプリケーションを作る上で最も難しい問題は、データやリソースを共有するスレッド間の調整 (coordination) です。この問題を解決するため、 threading モジュールではロックやイベント、状態変数、セマフォといった数々の同期プリミティブを提供しています。

こうしたツールは強力な一方、ちょっとした設計上の欠陥で再現困難な問題を引き起こすことがあります。したがって、タスク間調整では Queue モジュールを使って他のスレッドから一つのスレッドにリクエストを送り込み、一つのリソースへのアクセスをできるだけ一つのスレッドに集中させるアプローチを勧めます。スレッド間の通信や調整にQueue オブジェクトを使うと、設計が容易になり、可読性が高まり、信頼性が増します。

 


11.5 ログ記録

logging モジュールでは、数多くの機能をそなえた柔軟性のあるログ記録システムを提供しています。最も簡単な使い方では、ログメッセージをファイルや sys.stderr に送信します:

 

    import logging
    logging.debug('Debugging information')
    logging.info('Informational message')
    logging.warning('Warning:config file %s not found', 'server.conf')
    logging.error('Error occurred')
    logging.critical('Critical error -- shutting down')

上記のコードは以下のような出力になります:

 

    WARNING:root:Warning:config file server.conf not found
    ERROR:root:Error occurred
    CRITICAL:root:Critical error -- shutting down

デフォルトでは、単なる情報やデバッグメッセージの出力は抑制され、出力は標準エラーに送信されます。選択可能な送信先には、email、データグラム、ソケット、 HTTP サーバへの送信などがあります。新たにフィルタを作成すると、DEBUG, INFO, WARNING, ERROR, CRITICAL といったメッセージのプライオリティに従って配送先を変更できます。

ログ記録システムは Python から直接設定できますし、アプリケーションを変更しなくてもカスタマイズできるよう、ユーザが編集できる設定ファイルでも設定できます。

 


11.6 弱参照

Python は自動的にメモリを管理します (ほとんどのオブジェクトの参照回数をカウントし、ガベージコレクションによって循環参照を除去します)。オブジェクトに対する最後の参照がなくなってしばらくするとメモリは解放されます。

このようなアプローチはほとんどのアプリケーションでうまく動作しますが、中にはオブジェクトをどこか別の場所で利用するまでの間だけ追跡しておきたい場合もあります。残念ながら、オブジェクトを追跡するだけでは、オブジェクトに対する恒久的な参照を作ることになってしまいます。 weakref モジュールでは、オブジェクトを参照を作らずに追跡するためのツールを提供しています。弱参照オブジェクトが不要になると、弱参照 (weakref) テーブルから自動的に除去され、コールバック関数がトリガされます。弱参照を使う典型的な応用例には、作成コストの大きいオブジェクトのキャッシュがあります:

 

    >>> import weakref, gc
    >>> class A:
    ...     def __init__(self, value):
    ...             self.value = value
    ...     def __repr__(self):
    ...             return str(self.value)
    ...
    >>> a = A(10)                   # create a reference
    >>> d = weakref.WeakValueDictionary()
    >>> d['primary'] = a            # does not create a reference
    >>> d['primary']                # fetch the object if it is still alive
    10
    >>> del a                       # remove the one reference
    >>> gc.collect()                # run garbage collection right away
    0
    >>> d['primary']                # entry was automatically removed
    Traceback (most recent call last):
      File "<pyshell#108>", line 1, in -toplevel-
        d['primary']                # entry was automatically removed
      File "C:/PY24/lib/weakref.py", line 46, in __getitem__
        o = self.data[key]()
    KeyError: 'primary'

 

PR
PythonDjangoExcelファイルを作成
Chris McAvoy
海外internet.com発の記事http://mediajam.info/topic/518331
はじめに
 クライアントにデータを操作させる必要がある場合には、Excelのスプレッドシートを用意するのが最も簡単です。スプレッドシートはPythonを使って簡単に作成できますし、スプレッドシートをWebからダウンロードさせることも、DjangoというWebフレームワークを使えば簡単です。この記事ではスプレッドシートの進化の歴史について簡単に触れた後、この2つの操作方法について説明します。
スプレッドシートの進化の歴史
 サメは何百年もの間、あまり進化していません。その最大の理由は、野生で十分に生きていけるからです。獲物を実に上手く捕らえることができるので、サメは自らを適応させる必要も、変化する必要もなかったのです。これ以上進化させるところはないというほどに、サメは完璧な恐怖のフィッシュハンターです。

 サメと同様に、スプレッドシートも数十年の間、あまり進化してきませんでした。サメの例と同じく、スプレッドシートもデータを実に上手く処理することができるので、ほとんど進化する必要がなかったのです。スプレッドシードでは大量のデータを扱うことができ、データをわかりやすい表形式で表示でき、プログラマでない人でも、数値の並べ替えや操作を行ってデータを分析できます。スプレッドシートは完璧な恐怖のデータハンターなのです。
Webアプリケーションのデータ表示
 スプレッドシートはそれほど素晴らしいものなので、改良を試みて時間を無駄にするよりも、その能力を素直に認めた方が得策な場合もあります。Webアプリケーションの機能の大半は、「データベースのデータを受け取って、それをWeb上に配置すること」です。反復的開発環境では、最初の数サイクルは「データをデータベースに入力すること」に費やされます。この段階が終わると、開発の依頼主がWebアプリケーションにデータを表示させてみて欲しいと言い始めるでしょう。ここからが面倒なところです。

 表示して欲しいと求められたところで、そのデータを実際にどのように操作したいのかを正確に理解しているクライアントはほとんどいません。その時点では自分で理解しているつもりなのかもしれませんが、言われたとおりにして見せると、たいていは「思っていたのと何だか違う」という反応が返ってきます。

 これは別に、クライアントが意地悪をしているわけではありません。すべてのデータを一度に見るという経験はおそらく今まで1回もなかったのでしょうから、当然と言えば当然なのです。新しい形の情報をいじってみたら、今まで考えもしなかったパターンを思いついたというだけのことです。
Excelファイルを提供するWebアプリケーション
 このような経験から、筆者はできるだけExcelを使ってクライアントにデータを表示して見せるようにしています。データはクライアントがWebアプリケーションからダウンロードできるようにしておきます。Excelで自由に操作してもらった後なら、データをどのように利用し、最終的にどのように表示させたいかについて、優れたアイディアをクライアントから聞き出すことができます。時間を節約でき、製品の品質向上にもつながります。

 「データをExcel形式でダウンロード」ボタンを用意しておくと、データの可搬性という点でも大いに役立ちます。アプリケーションが完成に近づき、データの表示にExcelを使用する必要がなくなったときでも、Excelへのエクスポート機能を残しておき、ユーザーがデータをオフラインで利用できるようにしましょう。これはさまざまな難題を解決する、間違いなく魅力的な機能です。

 スプレッドシートの素晴らしさをご理解いただいたところで、以降ではその作成方法を説明し、続いて、必要なときすぐにWebアプリケーションからダウンロードできるようにする方法について解説します。

 今回の例ではWebアプリケーションフレームワークにDjangoを使用しますが、基本的な考え方はどのツールキットを使用する場合でも同じです。
PythonによるExcelスプレッドシートの作成
 Excelのフォーマットは(言うまでもありませんが)プロプライエタリです。ただし、オープンにしようと最善を尽くしてはいるようです。コンマ区切りのファイルをExcelで開き、Excelのスプレッドシートとして操作することは簡単にできます。また、コンマ区切りのファイルをPythonで作成することもいたって簡単です。PythonExcelcsvファイルを共通言語とする、最高に相性の良い組み合わせです。

 Pythonの標準ライブラリには、優れたcsv出力クラスが付属しています。次の短い例で、その使い方を紹介します。
import csv
w = csv.writer(open('output.csv','w'))
for i in range(10):
  w.writerow(range(10))
編集部注
 Windows環境で上記コードを実行した場合、改行コードが複数出力される現象が確認されています。
 この場合は、2行目の記述を以下のようにすれば問題を回避できます。
   w = csv.writer(open('output.csv','w'),lineterminator="¥n")
 output.csvの内容は以下のようになります。
0,1,2,3,4,5,6,7,8,9
0,1,2,3,4,5,6,7,8,9
0,1,2,3,4,5,6,7,8,9
0,1,2,3,4,5,6,7,8,9
0,1,2,3,4,5,6,7,8,9
0,1,2,3,4,5,6,7,8,9
0,1,2,3,4,5,6,7,8,9
0,1,2,3,4,5,6,7,8,9
0,1,2,3,4,5,6,7,8,9
0,1,2,3,4,5,6,7,8,9
 このファイルをExcelで開くと、区切り文字をたずねるダイアログが表示されます。コンマを選択すればそれで完了です。

 そうは言っても、csvファイルを開く際のこの一手間が、エンドユーザーのお気に召さないこともあります。そのような場合は、Roman Kiseliovが作成した、ExcelのバイナリファイルをPythonで作成するための素晴らしいライブラリを利用しましょう。これはpyExceleratorというライブラリで、Sourceforgeのプロジェクトページから入手可能です。このライブラリはWindowsExcelを必要としないので、もっと簡単に実行できます。

 前回のcsvの例と同じく、10×10列の表をpyExceleratorで作成してみましょう。
from pyExcelerator import *
wb = Workbook()
ws0 = wb.add_sheet('0')
 
for x in range(10):
   for y in range(10):
      # writing to a specific x,y
      ws0.write(x,y,"this is cell %s, %s" % (x,y))
 
wb.save('output.xls')
 先ほどとスクリプトは似ていますが、いくつか重要な違いがあります。pyExceleratorではWorkbookオブジェクトを明示的に作成し、そこにWorksheetオブジェクトを追加する必要があります。Worksheetにデータを書き込むときは、書き込み先の位置をx,yで指定します。この方法は柔軟性に優れていますが、書き込む際に表を頭に思い浮かべることが必要になります。

 pyExceleratorの方が少し手間がかかりますが、機能という点でははるかに上です。簡単な表データの作成に加え、セルの書式設定や、Excelの式の挿入など、Excelでよく使われる機能はひととおり網羅しています。csv出力クラスでは、簡単な表を作成することしかできません。
DjangoからのExcelファイルのダウンロード
 Excel互換ファイルをPythonで作成する方法を覚えたところで、次はそのファイルをDjangoでダウンロード可能にする方法を見ていきましょう。手順は簡単です。また、同じ手順でほとんどすべての種類のバイナリファイルを生成し、提供することができます。ファイルを作成できれば、それをユーザーにダウンロードさせるのは簡単です。

 鍵を握るのは「content-type」というHTTPヘッダーです。ブラウザからサーバー上のファイルを要求する場合、トランザクションは次のようになります。
GET /wp-content/uploads/2007/10/cropped-dsc_0020.jpg HTTP/1.1
Host: weblog.lonelylion.com
User-Agent:Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.11)
   Gecko/20071204 Ubuntu/7.10 (gutsy) Firefox/2.0.0.11
Accept: image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://lonelylion.com/
 
HTTP/1.x 200 OK
Date: Sat, 02 Feb 2008 17:53:58 GMT
Server: Apache/1.3.37 (Unix) mod_throttle/3.1.2 DAV/1.0.3
   mod_fastcgi/2.4.2 mod_gzip/1.3.26.1a PHP/4.4.8 mod_ssl/2.8.22
   OpenSSL/0.9.7e
Last-Modified: Thu, 01 Nov 2007 03:22:12 GMT
Etag: "798f213-5c88-47294664"
Accept-Ranges: bytes
Content-Length: 23688
Keep-Alive: timeout=2, max=97
Connection: Keep-Alive
Content-Type: image/jpeg
 最後の行のContent-Type: image/jpegに注目してください。この行は、後続のデータが何であるかをブラウザに伝えています。ブラウザはこの行に基づいて、データの表示方法や、どの外部アプリケーションを開いてデータを表示するかを判断します。

 上記の例ではJpegの画像を要求しているため、Content-Typeに「image/jpeg」が設定されています。このヘッダーを「application/ms-excel」に変更すると、ファイルがExcelで開かれます。Djangoでヘッダーの記述を変更するのは非常に簡単です。以下に、csvファイルをブラウザに送信し、それをExcelで開くようブラウザに指示するDjangoビューの例を示します。
import csv
from StringIO import StringIO
from django.http import HttpResponse
 
def show_excel(request):
   # use a StringIO buffer rather than opening a file
   output = StringIO()
   w = csv.writer(output)
   for i in range(10):
      w.writerow(range(10))
   # rewind the virtual file
   output.seek(0)
   return HttpResponse(output.read(),
      mimetype='application/ms-excel')
 最初のcsv作成の例にいくつか修正を加えました。まず、実際にファイルを開くのではなく、ファイルに似たStringIOオブジェクトを使用しています。また、応答をDjangoHttpResponseオブジェクトでラッピングしています(HttpResponseオブジェクトはDjangoビュー標準の戻り値のオブジェクトタイプです)。さらに、HttpResponsecontent_typeを渡すことによって、Content-Typeヘッダーを「application/ms-excel」に設定しています。

 このパターンを使用して、ほとんどすべての種類のバイナリデータをWebブラウザから取得することができます。PDF、画像、音声、動画など、あらゆるデータに対して生成用のライブラリが用意されているので、Content-Typeヘッダーの値さえわかれば、バイナリデータを生成することが可能です。

 それでは、同じテクニックを使ってpyExceleratorで生成したExcelファイルを出力してみましょう。
from pyExcelerator import *
from django.http import HttpResponse
 
def show_excel(request):
   wb = Workbook()
   ws0 = wb.add_sheet('0')
 
   for x in range(10):
      for y in range(10):
         # writing to a specific x,y
         ws0.write(x,y,"this is cell %s, %s" % (x,y))
 
      wb.save('output.xls')
   return HttpResponse(open('output.xls','rb').read(),
      mimetype='application/ms-excel')
 これもやはり、先ほどのpyExceleratorを使用してExcelファイルを作成した例に似ています。ただこのコードには1つ難があります。一時ファイルを作成してデータを書き込み、その後あらためてファイルを開き、そこからデータを読み込んでいるのです。この方法だと、トラフィックが多い場合に問題が起こる可能性があります。また、あるユーザーがファイルを読み込んでいる間に別のユーザーがそこにアクセスすると、ファイルが破損してしまうかもしれません。ファイル名にタイムスタンプを付加するという解決方法もありますが、最も理想的なのは、Workbooksaveメソッドにファイルに似たオブジェクトを渡してそこにデータを保存するという方法です。現在のpyExceleratorではこの方法は使用できませんが、必ずパッチが提供されると予想しています。

 筆者はたいていの場合、csvファイルを「Content-Type: application/ms-excel」としてブラウザに送信します。StringIOを使用すれば実装がシンプルになりますし、ダウンロード可能なスプレッドシートの作成にかかる時間は通常5分以内なので、ほとんどのエンドユーザーはおかしいとも感じません。これでユーザーの希望はかなえられますし、すぐにデータをいじってもらうことができます。ユーザーはデータをあれこれ操作することで、彼らが実際に使用するHTML表示についてより明確なビジョンを持つようになり、的確な要求をしてくるようになるでしょう。良いことだらけです。


忍者ブログ [PR]
お天気情報
カレンダー
03 2024/04 05
S M T W T F S
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
リンク
フリーエリア
最新CM
最新TB
プロフィール
HN:
No Name Ninja
性別:
非公開
バーコード
ブログ内検索
P R
カウンター
ブログの評価 ブログレーダー