有没有比使用全局变量从上下文管理器获取有趣值更好的方法?
@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__
方法。
我仍然认为你应该创建一个课程来控制你的错误/成功,就像我在你说的那样last question。我猜你有自己的类,所以只需添加这样的东西:
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__()
代码。编辑:正如Eli评论的那样,只有在想要重置coutner时才创建一个新的事务实例。
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