with ステートメントから興味深い値を返すにはどうすればよいでしょうか?
-
22-08-2019 - |
質問
コンテキストマネージャーから興味深い値を取得するには、グローバルを使用するより良い方法はありますか?
@contextmanager
def transaction():
global successCount
global errorCount
try:
yield
except:
storage.store.rollback()
errorCount += 1
else:
storage.store.commit()
successCount += 1
他の可能性:
シングルトン
一種のグローバル...
コンテキストマネージャーへの引数としてのタプル
関数をより問題に特化したものにする/再利用しにくくする
コンテキストマネージャーへの引数として特定の属性を保持するインスタンス
タプルと同じ問題がありますが、より読みやすくなっています
値を保持するコンテキスト マネージャーの最後で例外を発生させます。
本当に悪い考え
解決
http://docs.python.org/reference/datamodel.htmlを参照してください。 #コンテキストマネージャの
成功とエラーカウントを保持するクラスを作成し、その__enter__
と__exit__
メソッドを実装します。
他のヒント
私はまだ私は<のhref = "https://stackoverflow.com/questions/877440/try-except-except-how-あなたに言ったように、エラー/成功は、カウントあなたが保持するクラスを作成する必要があると思います回避・繰り返し・コード ">最後の質問に。私はちょうどそれにこのようなものを追加し、あなたがあなた自身のクラスを持って推測している。
class transaction:
def __init__(self):
self.errorCount = 0
self.successCount = 0
def __enter__(*args):
pass
def __exit__(self, type, value, traceback):
if type:
storage.store.rollback()
self.errorCount += 1
else:
storage.store.commit()
self.successCount += 1
(一度type
を呼び出す例外がない場合contextmanager
がNone)
そして、あなたはおそらくすでにcontextmanager
を起動し、あなたの__exit__()
コードを実行する、このどこかを使用しています。 編集のエリは、あなたがcoutnersをリセットしたいときのみ、新しいトランザクションインスタンスを作成し、コメントとして
t = transaction()
for q in queries:
with t:
t.execute(q)
コンテキストマネージャへの引数として「タプル
"/以下、再利用可能な問題への機能は、より具体的になり
はFalseます。
これは、コンテキストマネージャは、状態を維持させる。
あなたはこれ以上何も実装していない場合は、、それが再利用可能になります。
それは不変だからしかし、あなたが実際にタプルを使用することはできません。あなたは、いくつかの変更可能なコレクションを必要としています。辞書やクラス定義は気にしています。
その結果、推奨実装です。
「コンテキストマネージャへの引数として特定の属性を保持するインスタンス」
二つの属性を持つ単純なクラス定義はあなたが必要とするすべてです。しかし、あなたのトランザクション状態は、ステートフルであり、あなたがどこかの状態を保持する必要があります。
class Counters(dict):
SUCCEED= 0
FAIL= 1
def __init__( self ):
self[ self.SUCCEED ]= 0
self[ self.FAIL ]= 0
def increment( self, status ):
self[status] += 1
class Transaction(object):
def __init__( self, worker, counters ):
self.worker= worker
self.counters= counters
def __enter__( self ):
self.counters.status= None
def process( self, *args, **kw ):
status= self.worker.execute( *args, **kw )
self.counters.increment( status )
def __exit__( self ):
pass
counts= Counters()
for q in queryList:
with Transaction(execQuery,counts) as t:
t.process( q )
print counts