self - みる会図書館


検索対象: Pythonクックブック
189件見つかりました。

1. Pythonクックブック

1 1.9 init (self, master, queue, endCommand) : self. queue = queue # GUI のセットアップ def スレッドで G 団と非同期レ O を結合 ー 445 # 必要に応じ他の GUI 部品をここに加えるべし def processlncoming(self) : queue に現時点で存在するメッセージをすべて処理・ while self. queue. qsize( ) : try: Tkinter. Button(master, text='Done' , command=endCommand). pack( ) msg = self. queue ・ get(0) # メッセージ内容をチェックして必要なことを何でもやる。 # 簡単な例としてここでは p ⅱ nt を行う ( 実際にはもっとリッチに、 # GUI の表示を適切な形でアップテートすることになるだろう ) 。 print msg except Queue. Empty: # この場合この分岐が使われることはないと想定してはいるが、 # 一般原則としてはこの例外は無視 ! paSS class ThreadedClient(0bject) : GUI の "main" 部分とワーカースレッドの起動。 peri0dicCall と endApplication は GUI 部分に入れてもよいが、こちらに持ってくれは全てのスレッド制御をひとつの 場所で持っことになる。 def init (self, master) : GUI と非同期スレッドの開始。我々はアプリケーションの阮からある ) "main" スレッドの中に居るが、これは後から GUI で使われるものでもある。 ワーカー ( I / 0 ) スレッドはここで新たに spawn する。 self. master = master # キューの生成 self. queue = Queue. Queue( ) # GUI 部分のセットアップ self. gui = GuiPart(master, self. queue, self. endApplication) # 非同期 I / 0 を行うスレッドのセットアップ # 必要であれはさらなるスレッドの生成と利用が可能 self. running = True = threading. Thread(target=se1f. workerThread1) self. threadl self. threadl. start( ) # キューチェックのための GUI の定期呼び出しを開始 self. peri0dicCall( ) def peri0dicCall(self) : 200 ms ことにキューをチェックする一

2. Pythonクックブック

376 ー 9 章プロセスとスレッド、その同期 self. running = True def increment(self) : " カウンタを 1 増やす旧 self. val + = 1 def sendVa1(self, msg) : r. addHandler((cg. Process, 'value' ) , self. sendVal, cg. Message) self. increment) て . addHandIer('increment ・ = cg. Receiver( ) # さまざまなメッセージに対するハンドラ関数を登録する : " スレッドのエントリポイント旧 def run(self) : self. running = False running フラグを False にする def setStop(self) : req. send((cg. self( ) , self. val)) req = msg[0] スレッドの要求に応じカウンタの現在値を送信 " " て . receive( ) while self. running: # 停止リクエストがあるまで新規メッセージを処理し続ける r. addHandler('stop ・ , self. setStop) candygram の下で、このスレッドを起動するには : = cg. spawn(ExampleThread( ). run) counter とする。 counter スレッドのレスポンスを処理するにはもう 1 つ、適切なハンドラを登録した Reciever オプ ジェクトが要る : = cg. Receiver( ) response # 再度スレッドの現在値を要求、スレッドからのレスポンスをプリント counter. send(' increment ' ) # スレッドにもう一度 increment を命じる print response. receive( ) counter. send((cg. self( ) , 'value' ) ) # スレッドの現在の値を要求し、スレッドからのレスポンスをプリント counter. send(' increment ・ ) counter. send('incrementl ) # スレッドに increment を 2 度命じる オプジェクト counter および response はこのように使うはずだという例 : response. addHandler((counter, int), lambda msg: msg[l], cg. Message)

3. Pythonクックブック

] 3.1 4 ー the socket からのデータを全て受け取る。新しいデータの到着は timeout 秒まで待つ。データを文字列として返す一 # non-blocking のソケットを使う the socket. setblocking(o) total data = begin = time. time( ) while True: ー timeout までループー if total data and time. time( )-begin 〉 timeout: data = the socket. recv(4096) try: # データがまだ来ていないときは少し長く待つ break elif time. time( )-begin > timeout*2: # データが来ているときは timeout 秒後にフレイク break プロクシで SSL トンネリング ー 525 if data: total data. append(data) begin = time. time( ) else: time. sleep(). 1) except : paSS . join(total data) return class thread it(threading. Thread) : # 待ちの開始時間をリセット # テータに到着の猶予を与える トンネルやトンネルクライアントを実行するスレッドインスタンスロ = False init_(self, tid= ・ po て t = 0 , ip= threading. Thread. self. tid = tid self. proxy = proxy self. port = port self. server = server self. tunnel client = tunnel client done def server= , Proxy= , timeout=l): init_(self) self. ip = lp; self. port = port try: def run(self) : self. timeout = timeout self. data ー , tunnel client= ・ # 後で取り出すデータをひとますここへ トンネル動作実行中。サーバく - > プロクシ間をプリッジする一 if self. proxy and self. server: new socket = False while not thread it. done: if not new socket : new SOCket, address = self. server. accept( )

4. Pythonクックブック

260 ー Clas = None 考察 cf = (. f del cf 6 章 オブジェクト指向プログラミング self. self. else: self. else. if 0 func = fn is None: self. obj = None ・ self. obj = weakref. ref(o) self. func = f Clas def call_(self): # 持つ場合は結合メソッドである # 実は「非」結合だった場合 # ちゃんと結合してる場合 if self. obj is None: return self. func elif self. obj( ) is None: return None return new. instancemethod(self. func, self. 0bj( ) , self. clas) ぎり、オプジェクトをガべージコレクションで破棄することはできない・ 通常の結合メソッドは、オプジェクトへの強い参照を保持している。だから結合メソッドを破棄しないか class C(0bject): print " 〔 dying' def del_(self) : print " He110 " def f(self) : del ( ( dying # ( は虚ろな目でさまよい続けるのだ . # ... その結合メソッドを串刺しにするまでは。これで ( は死ぬ : この振る舞いは便利だが、ときにそれを望まないこともある。たとえばイベントディスパッチシステムを 実装する場合、イベントハンドラ ( すなわち結合メソッド ) がただ存在するだけで、結合元のオプジェクトを 再利用できないようでは困ってしまう。直観的には、弱参照を使えばこの問題が解決できると思うかもしれ ない。ところが weakref. ref で結合メソッドに弱参照を行っても、思ったとおりには動かない。これは結合メ ソッドが独立したファーストクラスオプジェクトだからである。このため結合メソッドへの弱参照は、作っ た途端に dead になってしまう。つまり他に強い参照がない限り、すでに破棄されたオプジェクトへの参照と みなされ、常に None を返すのである。 たとえば、次のように weakref モジュールを使った場合、 None は関数呼び出しできないという例外が発生し てしまう。 cf = weakref. ref(). f) import weakref cf # うぬ、もっと電撃が必要だな。おいアイゴール・

5. Pythonクックブック

2. ] 3 C + + 的な iost 「 eam シンタックスを使う一 2.13 C + + 的な iostream シンタックスを使う ライプラリリファレンスおよび「巧′ thon クイックリファレンス』の msvcrt モジュールに関する解説。 参照 解法 のを使いたい。 ある特別なオブジェクト ) を基本とするアプローチが好きなので、 python プログラムでもそんな C + + のように、 I/O に対して ost 「 eams とマニュピレータ ( ストリームに挿入すると特殊な効果の 問題 Credit: Erik Max Francis 訳 : 吉宗貞紀 83 thon では、作成したクラスで特殊メソッド ( メソッドの名前の最初と最後が 2 つのアンダースコアである もの ) を再定義することで、演算子をオーバーロードできる。くくを c + + でやっているように出力に用いたいの であれば、くくに対応する特殊メソッドである lshift メソッドを再定義するアウトブットストリームクラ スを書けばよい class 10Manipulator(0bject) : init (self, function=None) : def self. function def do(self, output) : self. function(output) def do endl(stream) : stream. output. write(' \n' ) stream. output. flush( ) = 10Manipulator()0 endl) endl class 0Stream(0bject) : init (self, output=None) : def if output is None: import sys output = sys. stdout self. output = output self. format = def _lshift_(self, thing) : ・くく演算子を使用したときに Python が呼び出す特殊メソッドで 左側のオペランドが 0Stream である一 if isinstance(thing, 10ManipuIator) : thing. do(self) = function else: self. output. write(self. format % thing) self. format = return self

6. Pythonクックブック

い .9 スレッドで G げと非同期レ O を結合ー 447 レシピでは select でワーカースレッドをプロック化する場合を想定した ( レシピのワーカースレッド例では ランダムなスリープによってシミュレートしている ) 。ワーカースレッドは何かが到着すればこれを受け取り、 Queue インスタンスに入れる。メイン (GUI) スレッドは Queue に対し、秒に 5 回のポーリングを行い、前回の チェック後に到着したメッセージをすべて処理する ( 5 回 / 秒のポーリングはユーザに気付かれる遅れを生じ ないほど頻繁で、コンピュータの負荷がほとんど上がらないほどまばらである ) 。この部分は必要に応じて チューンしたいかもしれない。 このレシピは Python のメーリングリストやニュースグループの類で頻繁に出る質問に対する回答である。 別解としてスレッド間同期によるものがあり、こちらはポーリング ( レシピにおける self. master. after のコー ル ) を使わすにこの種の問題を解決する。しかしスレッド間同期ではコードがセマフォアだらけになる傾向が あり、複雑かっ巨大なのが一般的だ。 GUI にはどうせ多少のポーリング機構が ( 、、 main " イベントループとし て ) 組み込まれているので、もう 1 つ持って来ても大した違いはない。特に単独で走らせるプログラムではそ うである。このコードのちゃんとしたテストは Linux でしかしてないが、スレッドの動くプラットフォーム なら Windows ででもちゃんと動くはすである。 以下はほんの僅かな変更を加えた Qt 版である : import sys, time, threading, random, 0ueue, qt class GuiPart(qt. QMainWindow) : init (self, queue, endcommand, *args) : def qt. QMainWindow. init (self, * args) self. queue = queue # 結果をコンソールでなく GUI に表示 = qt. QMultiLineEdit(self) self. editor self. setCentralWidget(self. editor) = endcommand self. endcommand def cIoseEvent(self, (v) : 終了ボタンを提供したりはせす、単にウインドウを閉じると endcommand をコールするようにした。 self. endcommand( ) def processlncoming(self) : queue に現時点で存在するメッセージをすべて処理 " while self. queue. qsize( ) : try: = self. queue. get(0) msg self. editor. insertLine(str(msg)) except Queue. Empty: paSS class ThreadedClient(0bject) : GUI の "main" 部分とワーカースレッドの起動。 peri0dicCalI と endApplication は GUI 部分に入れてもよいが、こちらに持ってくれば全てのスレッド制御をひとつの場所で持っことになる。

7. Pythonクックブック

590 ー ] 5 章分散プログラミング 15.9 telnetlib でリモートログイン credit: Jeff Bauer 訳 : 吉田聡、鴨澤眞夫 解法 Telnet プロトコルでよい。 問題 ローカルマシンあるいはリモートマシンに対してログインしてコマンドを送る必要がある。 モジュール telnetlib が、 TeInet を利用するあらゆる場合をよくサポートしている。 ケットの盗聴や詐称攻撃が可能なため、ほとんどはイントラネットの中だけで使われる ) 。 thon では、標準 TeInet は TCP / IP スタックの中でも最古に属するプロトコルであるが、いまだに使われることがある ( パ , user if login prompt in response: response = t. read until(login prompt, 5 ) login prompt = "login: t. write("\n") t = self. telnet # login プロンプトを待つ def action(self, user, cmd list) : self. telnet. close( ) print "Unable t0 process: if not ok : = self. action(user, cmd list) self. telnet. open(self. host) # 指定のホストとユーザ名でログインし、適切に行動する fO て user in user 1iSt: self. telnet = telnetlib. Telnet( ) # Telnet プロクシのインスタンス化 self. passwd[user] = getpass("Enter user '%s' password: " % user) fO て user in user list: self. passwd = # 各ユーザのバスワードを対話的に収集 self. command prompt = kw. get(' command_prompt ' self. timeout = kw. get(' timeout ・ , 600 ) self. host ・ localhost つ = kw. get('host ・ # できたときのコマンドプロンプトである : # オプションバラメタは host 、タイムアウト秒数、正しく口クイン def init (self, user list, cmd list, **kw) : class Aut0Telnet(0bject) : 行 getpass import getpass import os, sys, telnetlib # autO telnet. py - telnet を使ったリモートコントロール

8. Pythonクックブック

5. ] 2 シーケンスにアイテムの存在チェックをかける一 221 内側ループは、もし等値アイテムが見つかればすぐに True で終了するが、 Fa1se で終了するのは等値アイテム が見つからすにループが終了したときのみだ。だから平均すると、 in オペレータの実行には len(baseList) に 比例した時間がかかることになる。 addUnique_simp1e は 1en(0therList) 時間で実行されるので、総合すれば両 リストの長さの「積」に比例した時間的振舞いをもっことになる。 「解法」で示した関数 addUnique では、まず補助ディクショナリ auxDict を構築しており、ここで 1en(baseList) に比例した時間がかかる。続いてループ内側の in オペレータが dict に存在チェックをかける。全ての違いは このステップにある。つまり dict に対する存在チェックの時間は大まかに言えば定数であり、 dict 内のアイ テム数とは独立しているのだ ! というわけでループは len ( 0therList ) に比例した時間となり、関数全体では 両リストの長さの「和」に比例した時間的振舞いをもつ。 実行時間分析は、実は結構深いところまで行う必要がある。これは addUnique_simple において baseList が定 数ではない、つまり、もともとなかったアイテムを処理する度に baseList は大きくなるためである。しかし この ( 驚くほど複雑な ) 分析をかいつまんでやると、結局は簡単な分析とあまり変わらないものが出てくる。両 リストに 10 個の整数があり、 50 % が重複していた場合、 simple バージョンは「解法」のものより 30 % 遅い程 度である。ところがアイテム数が 100 個になると、 simple は「解法」のなんと 12 倍遅い。この速度低下はと ても無視などできないし、これはリストが大きくなるほど悪化するのだ。 シーケンスに恒久的に補助 dict を添えて単一のオプジェクトにまとめることにより、総合性能がさらに良 くなる場合がある。ただしこの場合、シーケンスに手が加わったときには補助 dict が現状に同期するよう保 証しなければならない。このメンテナンスタスクは結構な難物だが、いろいろやり方はある。ここに小すの は同期を "justintime" で行うもので、存在テストが要求されたときリストの内容との同期が外れている可 能性があると、補助 dict を再構築する。以下のクラスでは存在チェックだけでなく、 index メソッドも最適化 しているが、これにはほとんどコストがかかっていない・ class list with aux dict(list) : init_(self, iterable=( ) ) : def init_(self, iterable) list. self. dict ok = False def rebuild dict(self) : self. dict = { } for i, item in enumerate(self) : if item not in self. dict : self. dict[item] self. dict ok = True def contains (self, item) : if not self. dict ok: self. rebuild dict( ) return item in self. dict def index(self, item) : if not self. dict ok: self. rebuild dict( ) try: return self. dict[item]

9. Pythonクックブック

ート 5.4 キーやインデックスを、その値によりソ ー 203 5.4 キーやインデックスを、その値によりソート credit: John Jensen, Fred Bremmer, Nick Coghlan 訳 : 鴨澤眞夫 問題 さまざまなアイテムの出現度数を調べ、出現度数順にソートする必要がある。たとえばヒストグ ラムを作るためである。 解法 ストやディクショナリなら簡単 ) し、続いてキーやインデックスを ( 対応の ) 値でソートすることだ。この 2 つ ヒストグラムの基盤とは、グラフィックの問題を別にすれば、アイテムの出現度数をカウント ( thon のリ のメソッドを加えた dict のサプクラスは、以下のようになる : class hist(dict) : def add(self, item, increment=l) : increment を item のエントリに加える self[item] = increment + self. get(item, 0 ) def counts(self, reverse=False) : ー対応の値でソートしたキーのリストを返す一 = [ (self[k], k) k in self ] aux aux. sort( ) if reverse: aux. reverse( ) return [k for v, k in aux] 数えるアイテムが小さな範囲の整数で表現できるものであり、 下となる。解は非常に似たものである : class histl(list): init_(self, n): def リスト中に出現度数を保持したい場合は以 ー n 個の異なるアイテムの出現度数を数えられるようにリストを初期イい init_(self, n*[o]) list. def add(self, item, increment=l) : increment を item のエントリに加える self[item] + = increment def counts(self, reverse=Fa1se) : ' 対応の値でソートしたインテックスのリストを返す ' = [ (), k) f0 て k, v in enumerate(self) ] aux aux. sort( ) if reverse: aux. reverse( ) return [k for v, k in aux]

10. Pythonクックブック

434 ー 考察 ロ章ユーザインタフェース def shiftSelection(self, event) : = self. nearest(event. y) 1 if i く self. curlndex: = self. get(i) X self. delete(i) self. insert(i + 1, x) self. curlndex elif i 〉 self. curlndex: = self. get(i) self. delete(i) self. insert(i-l, x) self. curlndex 作成したクラス DDList の使用例を以下に示す。例によって if モジュールの一部としても利用できるし、単体のコードとして動かすこともできる。 name maln ーを利用しているので、 if name maln tk = Tkinter. Tk( ) length ニ 10 dd = DDList(tk, height=length) dd. pack( ) fo て i in xrange(length) : dd. insert(Tkinter. END, str(i)) def show( ) : 凵現在の並びを 2 秒間隔で表示する一 for x in dd. get(), Tkinter. END) : print x, print tk. afte て ( 2000 , show) tk. after(2000, show) tk. mainloop( ) 1999- May / ) である。 このレシピのコードの一部は Fredrik Lundh が投稿したもの (http://mail.python.org/pipermail/python-list/ きな問題を引き起こすとは考えにくいが、見た目的には妙な感じがする。 リックされたリストの代わりに、選択されていないはずのリストが動くようになってしまう。このことが大 択されている状態 " を保とうと試みる。しかし、処理が追いつかないくらいの速度でマウスを動かすと、ク このレシピのコードでは、クリックされたリストは隣のリストを消し、反対側に挿入する動作を取って " 選 ある。このレシピでは、 Tkinter のリストボックスに、この機能を簡単に実装する方法を示している。 GUI プログラム上のリストの順序をドラッグすることで変更できるようにしておくと、便利な場面が結構