Python 如何在';与';陈述

Python 如何在';与';陈述,python,ironpython,Python,Ironpython,我正在尝试用漂亮的Python包装器包装一个.NET库,以便在IronPython中使用 此库中经常使用的一种模式是PersistenceBlock,用于清除数据库CRUD操作和“全部或全无”: try: Persistence.BeginNewTransaction() # do stuff here Persistence.CommitTransaction() except Exception, e: Persistence.AbortTransaction() Log

我正在尝试用漂亮的Python包装器包装一个.NET库,以便在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的正确实现吗?我可能会错过什么

让我感到困惑的主要问题是持久性是一个静态的.NET类,因此没有正常意义上的“实例”可管理


我尝试过搜索,但是单词“with”压倒了结果:(

您可以通过搜索
上下文管理器
协议找到文档-这是所有对象都应该使用
with
语句的协议

上下文管理器(即
\uuuuuuuuuuuuuuuuuu enter\uuuuuuuu
方法)不需要返回任何内容-仅当您希望将
与…as…
语法一起使用时才需要返回。在
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu退出\uuuuuuuu
方法中,您必须执行一些正确的错误检查:如果存在异常,则重新引发

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
为了完整性,您还可以使用decorator使用一个简单的生成器实现您的上下文:

import contextlib

@contextlib.contextmanager     
def PersisenceContext():

    try:
        yield Persistence.BeginNewTransaction()
    except Exception:
        Persistence.AbortTransaction()
        raise
    else:
        Persistence.CommitTransaction()
    finally:
        Persistence.CloseTransaction()

contextlib可能比实现接口更惯用,更容易理解。它当然更容易编写-但我实际上怀疑它在编写第一个上下文管理器时更容易理解。
enter
exit
至少在某种程度上是自我解释的……这正是我想要的。仅供参考我一直使用的IronPython版本不支持contextlib,但第一个示例完全按照预期工作。这为我指明了正确的方向,同时我研究了IronPython和contextlib的版本问题。我还需要进行更多的异常测试,以确保涵盖这些基础。我正在观看Hettinger的视频以了解更多信息。谢谢!