我正在尝试将.NET库包装在漂亮的pythonic包装器中,以便在IronPython中使用。
这个库中经常使用的模式是PersistenceBlock,它可以使数据库CRUD操作变得干净,并且全部或全部都没有':
try:
Persistence.BeginNewTransaction()
# do stuff here
Persistence.CommitTransaction()
except Exception, e:
Persistence.AbortTransaction()
Log.Error(e)
finally:
Persistence.CloseTransaction()
我想将它包装在允许这种代码的类中:
with PersistenceBlock:
# do stuff here
这就是我提出的:
class PersistenceBlock():
def __init__(self):
def __enter__(self):
return self
def __exit__(self, exctype, excinst, exctb):
try:
Persistence.BeginNewTransaction()
yield
Persistence.CommitTransaction()
except:
Persistence.AbortTransaction()
Log.Error(e)
finally
Persistence.CloseTransaction()
这是PEP343的正确实施吗?我可能会失踪什么?
主要的问题是Persistence是一个静态.NET类,因此没有'实例'正常意义上的管理。
我尝试过搜索,但用“'压倒了这些结果:(
答案 0 :(得分:4)
您可以通过搜索context manager
协议找到文档 - 这是所有应该与with
语句一起使用的对象应该实现的协议。
只有当您想使用__enter__
语法时,上下文管理器(即with ... as ...
方法)才需要返回任何内容。在__exit__
方法中,您必须进行一些正确的错误检查:如果存在异常则重新引发异常,如果不存在则重新引发异常。也许是这样的:
class PersistenceContext():
def __enter__(self):
# when opening the block, open a transaction
Persistence.BeginNewTransaction()
def __exit__(self, exctype, excinst, exctb):
if excinst is None:
# all went well - commit & close
Persistence.CommitTransaction()
Persistence.CloseTransaction()
else:
# something went wrong - abort, close and raise the error
Persistence.AbortTransaction()
Persistence.CloseTransaction()
raise exctype, excinst, exctb
为了完整性,您还可以使用contextmanager装饰器使用简单的生成器实现您的上下文:
import contextlib
@contextlib.contextmanager
def PersisenceContext():
try:
yield Persistence.BeginNewTransaction()
except Exception:
Persistence.AbortTransaction()
raise
else:
Persistence.CommitTransaction()
finally:
Persistence.CloseTransaction()