8

グローバルを使用してコンテキストマネージャから興味深い値を取得するよりも良い方法はありますか?

@contextmanager
def transaction():
    global successCount
    global errorCount
    try:
        yield
    except:
        storage.store.rollback()
        errorCount += 1
    else:
        storage.store.commit()
        successCount += 1

その他の可能性:

  • シングルトン

    一種のグローバル...

  • コンテキストマネージャへの引数としてのタプル

    関数をより問題に特化したものにする / 再利用性を低くする

  • コンテキストマネージャへの引数として特定の属性を保持するインスタンス

    タプルと同じ問題だが、より読みやすい

  • 値を保持しているコンテキストマネージャーの最後で例外を発生させます。

    本当に悪い考え

4

3 に答える 3

9

http://docs.python.org/reference/datamodel.html#context-managersを参照してください

__enter__成功数とエラー数を保持し、 メソッドとメソッドを実装するクラスを作成します__exit__

于 2009-05-18T13:31:38.547 に答える
0

「コンテキストマネージャへの引数としてのタプル

関数を問題に特化したものにする / 再利用性を低くする"

間違い。

これにより、コンテキスト マネージャーは状態を保持します。

これ以上何も実装しなければ、再利用可能になります。

ただし、タプルは不変であるため、実際には使用できません。可変コレクションが必要です。辞書とクラス定義が思い浮かびます。

したがって、推奨される実装は次のとおりです。

「コンテキストマネージャーへの引数として特定の属性を保持するインスタンス」

必要なのは、2 つの属性を持つ単純なクラス定義だけです。ただし、トランザクション ステータスはステートフルであり、どこかで状態を保持する必要があります。

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
于 2009-05-18T14:21:02.427 に答える