如何在'中包含一个静态类(来自.NET)声明

时间:2016-07-12 14:47:11

标签: python ironpython

我正在尝试将.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类,因此没有'实例'正常意义上的管理。

我尝试过搜索,但用“'压倒了这些结果:(

1 个答案:

答案 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()