直接コードに:
インポート要求 のインポートCSVファイル から contextlib インポートクロージング #は、CSVファイルの保存 DEFのsave_csv(F_NAME、データ): #ファイルオブジェクトを作成します。1. (F_NAME、F =オープンは' Wを' =エンコードする、'UTF-8 '、NEWLINE = '' )# を2.書き込み対象のファイルに基づいて構築されたCSVオブジェクト csv_writer = csv.writer(F) #4 SUMMARYのcsvファイルが書き込まれているため、行にデータ: csv_writer.writerow(行)の#5。近いファイル f.close() #のダウンロードのcsvをファイル DEF :)(get_pag URL = ' ******** ' #数据读取 (requests.get(URL、ストリーム=閉鎖で:R真))を F =(line.decode(' UTF-8 ')のためのラインでr.iter_lines()) リーダー = csv.reader(F、デリミタ= ' '、quotechar = ' " ' ) save_csv(F_NAME、リーダー)場合__name__ == ' __main__ ' : F_NAME = ' 123.csv 「 リーダー = get_pag()
ここのハイライト:
contextlib.closing、ライブラリーを研究。
:CONN1としてXXXと
conn2としてYYYを持つ:
コード
それは実際にあることができるよう、本当に愚かな老犬:
:CONN1、conn2としてYYYなどXXXと
コード
contextlib インポートクロージング から urllib2の輸入urlopen (urlopen(クローズと「http://www.python.org 」を:ページとして;)) のためのラインでのページ: プリント(ライン)
すべてが私を助けるために、自動的に、シャットダウンを使用したと罰金になります私のアイデアを、否定する最初の。
クラスドア(オブジェクト): DEF オープン(自己): 印刷 「のドアが開かれた」 DEF 近い(自己): プリント 「ドアが閉じている」 dとドア()と: d.open()
結果:
#报错: トレースバック(最新の呼び出しの最後): ファイル" 1.py "、38行、で、<モジュール> dとドア()を持つ: はAttributeError:__exit__
クラスのドア(オブジェクト): デフオープン(自己): プリント ' ドアが開いている' DEF 近い(自己): プリント ' のドアが閉じている' contextlib.closingで(ドア())ドアのように: door.open()
結果:
ドアがされて開かれた 扉があり、閉鎖
以下のように(XXX)をcontextlib.closing、動作します:
クラスクロージング(オブジェクト): 「」」ブロックの終了時に自動的に近いものにコンテキスト。 このようなコード: 閉じると(<モジュール> .open(<引数>))は、fとして: <ブロック> これに相当します。 F = <モジュール> .open(<引数>) のtry: <ブロック> 最後に: f.close() ""」 デフ __init__ (自己、事): self.thing = 事 デフ __enter__ (自己): 戻りself.thing デフ __exit__(自己、* exc_info):* self.thing.close()
このcontextlib.closingは()という条件を満たすことで、__それは__enter追加()と__exitを__()するのに役立ちます。
5、あなたと利便性を享受するための唯一のクラスではありませんか?私はちょうど方法だ大丈夫?
OK!()をcontextlib.closing会ったので、それはcontextlib.contextmanagerの下で認識されなければならない
。このデコレータで、あなたは(FUNCを作ることができる)の条件を持つクラスのインスタンスになります...
!!!このFUNC()...発電機がなければなりません
前半に得__ __enterを表し、()
収率は半分__exitを示すために使用された後、__()
contextlib 輸入contextmanager @contextmanager デフタグ(名前): 印刷(" <%S> "%の名称) 降伏 プリント(" </%sの> "%の名称) タグ(との" H1 " ): 印刷 " こんにちは、世界!"
結果:
<H1>
のHello World!
</ H1>
インポート時間 DEF ラッパー(FUNC): DEF new_func(*引数、** kwargsから): T1 = time.time() RET = FUNC(*引数、** kwargsから) T2 = time.time() 印刷 ' 費用時間= '、(T2- T1) リターンRETの 復帰new_func @wrapper DEF ハロー(B): time.sleep( 1 ) 印刷 ' + B = '、+のBの ハロー( 100,200)
結果:
A + B = 300
、コスト、時間 = 1.00243401527
contextmangerバージョン:
contextlibのインポートcontextmanager @contextmanager DEF cost_time(): T1 = time.time() 収率 T2 = time.time() 印刷 ' 費用時間= '、T2- T1 とcost_time(): time.sleep( 1 ) = 100 B = 200 プリント ' + B = '、+ bの
結果:
A + B = 300
、コスト、時間 = 1.00032901764
もちろん、ビューの米国のポイントは、〜デコレータを使用するのは簡単です
これはcontextmanager原理である:
1、funcが()contextmanagerコールself.gen.nextは()FUNCの収率に行くとき、まあ、そう実行__enter __()、これを保留停止し発電機を持っているので、 time.time時間を有し= T1()
2、その後体内声明文で実行、すなわち、300 = B +
3、__exit仕上げ__(実行後)場合、ContextManagerコールself.gen.next( )文の最後まで、最初からFUNCを得られます。T2 = time.time()、T2-とこの時刻 T1 統計cost_time、完璧の効果を達成するためです。
出典:
クラスGeneratorContextManager(オブジェクト): "" " @contextmanagerデコレータのヘルパーです。""" デフ __init__ (自己、GEN): self.gen = GEN デフ __enter__ (自己): 試してみる: リターンself.gen.next() を除いて呼び出すとStopIteration: 調達はRuntimeErrorを(「発電機が得られなかった」) デフ __exit__ (自己、タイプ、値、トレースバック): あれば型がある:なし 試し: self.gen.next() を除いて呼び出すとStopIteration: リターン 他: 昇給はRuntimeError(「発電機を停止しませんでした」) それ以外: 場合値がある:なし #1 私たちが確実にできるよう力をインスタンス化する必要が #私たちは同じ例外バック得れば教えて 値を= タイプ() してみてください: self.gen.throw(タイプ、値、トレースバック) 昇給はRuntimeError(「発電機が(スロー後に停止しませんでした)" ) を除くEXCを呼び出すとStopIteration、: リターン EXCがある ではない値 を除く: もし(sys.exc_info)[1]はあり ません値: 昇給 デフcontextmanager(FUNC): @wraps(FUNC) デフヘルパー(* argsを、** kwds): リターン GeneratorContextManager(FUNC(* argsを、** kwds)) 戻りヘルパー
ブロガーありがとう ouyangbro さんのブログ https://blog.csdn.net/emaste_r/article/details/78105713
ブロガーに感謝 ビッグローファー のブログ https://blog.csdn.net/t8116189520/article/details/103408560を