今日のPython
スレッドのロック
p.374 RLockオブジェクトを使ってクリティカルセクション(ロック〜アンロック)を作る例
lock = threading.RLock() #クリティカルセクションを開始 try: # スレッドの実行コード finally: lock.release() #ロックを解放
pythonでCGIを利用する
事前準備 - Macでサーバー環境を整える
CGIを動かす前に、ローカルでサーバーとして動く環境を作る。MacはOS X 10.5.2
Apacheを稼働
Macでは最初からApacheが入っているので、これを稼働させる。
システム環境設定 -> 共有 -> Web共有 をオン
この状態でhttp://127.0.0.1/ もしくは http://localhost/ にアクセスし、Apacheが動いていることを確認する。
ファイルの置き場所について
ローカルサーバ上で参照されるファイルのアドレスは、
htmlなどのファイル:/Library/WebServer/CGI-Executables/Documents
CGI:/Library/WebServer/CGI-Executables/
スクリプトファイル
p.379
#!/Library/Frameworks/Python.framework/Versions/Current/bin/python # -*- coding: utf-8 -*- import cgi import cgitb; cgitb.enable() import calendar import time calendar.setfirstweekday(6) #カレンダーの最初の曜日を日曜日に設定 year, month = time.localtime()[:2] form = cgi.FieldStorage() #CGIに渡されたデータを取得 year = int(form.getvalue("year", year)) month = int(form.getvalue("month", month)) # 西暦、月、曜日を表示 b = """<tr><th colspan="7">%d,%d</td></tr>""" % (year, month) b += "<tr>" for wname in ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]: b += "<th>%s</td>" % wname b += "</tr>" # カレンダーを表示 for week in calendar.monthcalendar(year, month): b += "<tr>\n" for day in week: if day: b += "<td>%d</td>" % day; else: b += "<td> </td>"; #半角スペース # ヘッダ、HTMLを出力 print "Content-type: text/html\n" print "<html><body>" print """<table border="1"> %s </table>""" % b print "</body></html>"
1行目は、ターミナルで「$ which python」と入力し、表示された値。今までの「#!/usr/bin/env python」だとうまく動かなかった。
これをtest.cgiなどの名前で保存し、/Library/WebServer/CGI-Executables/に設置する。
次にパーミッションを変更する。以下のコマンドで。
$ chmod 755 /Library/WebServer/CGI-Executables/test.cgi
http://127.0.0.1/cgi-bin/test.cgiへアクセス。実行結果が表示される。
2008,5 Sun Mon Tue Wed Thu Fri Sat
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 31
PythonでCGI動いたよ!やったー!
プログラムのテスト
doctestモジュール
p.388
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' complete.py 完全数を探す ''' def get_divisor(number): """ 約数を探してリストにして返す >>> import complete >>> complete.get_divisor(2) [1] >>> complete.get_divisor(6) [1, 2, 3] >>> complete.get_divisor(100) [1, 2, 4, 5, 10, 20, 25, 50] """ return [cnt for cnt in range(1, number) if number % cnt == 0] def is_complete(number): """ 数値が完全数かどうか調べ、boolで返す >>> import complete >>> complete.is_complete(6) True >>> complete.is_complete(428) False >>> complete.is_complete(496) True """ if sum(get_divisor(number)) == number: return True; else: return False; if __name__ == "__main__": import doctest #doctestモジュールをインポートする doctest.testmod() #doctestを実行する for cnt in xrange(1, 1001): if is_complete(cnt): print cnt,
インタラクティブシェルでスクリプトをモジュールとして読み込み、関数単位?での実行結果をスクリプト内にコメントとして貼り付けておくと、doctestモジュールがその結果と照らし合わせてくれる。
普通、ファイルとして実行した場合にテストを行うので、doctestはif __name == "__main__":ブロック内に記述する。
実行結果:成功例(普通に実行される)
$ python complete.py 6 28 496
実行結果:失敗例
$ python complete.py ********************************************************************** File "complete.py", line 12, in __main__.get_divisor Failed example: complete.get_divisor(5) Expected: [1, 2, 3] Got: [1] ********************************************************************** 1 items had failures: 1 of 4 in __main__.get_divisor ***Test Failed*** 1 failures. 6 28 496
SQLiteを利用する
python2.5ではsqlite3というモジュールがあるので、それを利用する。
p.404 PythonとSQLiteを使ったサンプルプログラム
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' sqltest.py SQLiteのサンプルプログラム 郵便番号と住所を管理する ''' import sqlite3 # 郵便番号のリスト postno = [[u"東京都千代田区", "100-0000"], [u"東京都千代田区飯田橋", "102-0072"], [u"東京都千代田区一番町", "102-0082"], [u"東京都千代田区岩本町", "101-0032"],] # コネクションオブジェクトを作る con = sqlite3.connect(":memory:") cur = con.cursor() #カーソルを作る # テーブルを作成 cur.execute("""CREATE TABLE postdb(address text, postno text)""") # データを登録 for item in postno: cur.execute("""INSERT INTO postdb(address, postno) VALUES(?,?)""", item) # データを選択、表示 cur.execute("SELECT * FROM postdb WHERE postno=?", ("102-0072",)) data = cur.fetchone() print data[1], data[0]
実行結果
$ python sqltest.py 102-0072 東京都千代田区飯田橋
SQLを理解していないから色々いじることができない・・・今後の課題。
GUIアプリケーション
Tkinterを使ったGUI構築サンプル
p.435
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' tkinter.py GUIアプリケーションのサンプル ''' from Tkinter import * import time class App(Frame): TIME = 10 * 3 #タイマー待ち時間 def __init__(self, master=None): "初期化用メソッド" Frame.__init__(self, master) self.time = 0 self.master.title("Tk Timer") #フレームタイトル self.timestr = StringVar() self.timestr.set("00:30") l = Label(self, textvariable=self.timestr, font=('Halvetica', '48', 'bold')) b1 = Button(self, text="Start", command=self.countdown) b2 = Button(self, text="Quit", command=self.master.destroy) for obj, sideparam in ((l, TOP), (b1, LEFT), (b2, RIGHT)): obj.pack(side=sideparam) self.pack() def countdown(self): "タイマーの時間を減らしていくメソッド" if self.time == 0: self.time = time.time() timeleft = max(self.TIME-(time.time()-self.time), 0) min, sec = (timeleft) / 60, timeleft % 60 self.timestr.set("%02d:%02d" % (min, sec)) self.after(1000, self.countdown) if __name__ == "__main__": app = App() app.mainloop()
とりあえずソースだけ。Tkinterモジュールを使うとGUIアプリが作れます。すげえええ
みんPyおわり!
後半かなり駆け足だったけど、ひとまずみんなのPythonは読み終えました。基本的な文法やモジュールの使い方は理解できたので、あとは自分の考えたものを作れるようにゴリゴリ書いていきます。これにて「今日のPython」シリーズは、終わりです。
学習開始日:4/22 - Python始めました
何日かかったかな?
>>> import datetime >>> d1 = datetime.date(2008, 4, 22) >>> d2 = datetime.date(2008, 5, 15) >>> print d2 - d1 23 days, 0:00:00
23日かかりました!datetimeモジュールも大変便利ですね。それではごきげんよう。
- 作者: 柴田淳
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2006/08/22
- メディア: 単行本
- 購入: 11人 クリック: 624回
- この商品を含むブログ (180件) を見る