有没有比使用全局变量从上下文管理器获取有趣值更好的方法?

@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#context-managers

创建一个类来保存成功和错误计数,并实现 __enter____exit__ 方法。

其他提示

我仍然认为您应该创建一个类来保存错误/成功计数,正如我在您中所说的 最后一个问题. 。我猜你有自己的课程,所以只需添加这样的内容即可:

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 如果调用后没有异常则为 None contextmanager)

然后你可能已经在某个地方使用它了,这将调用 contextmanager 并运行你的 __exit__() 代码。 编辑: 正如 Eli 评论的那样,仅当您想要重置计数器时才创建新的事务实例。

t = transaction()
for q in queries:
    with t:
        t.execute(q)

“元组作为上下文管理器的参数

使函数更具体地解决问题/可重用性降低”

错误的。

这使得上下文管理器保留状态。

如果您不实现除此之外的任何内容,它将是可重用的。

但是,您实际上无法使用元组,因为它是不可变的。你需要一些可变的集合。我想到了字典和类定义。

因此,建议的实施是

“将特定属性作为上下文管理器的参数的实例”

您只需要一个具有两个属性的简单类定义。但是,您的事务状态是有状态的,您需要在某处保留状态。

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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top