pytool icon indicating copy to clipboard operation
pytool copied to clipboard

Python上下文管理器

Open limboinf opened this issue 8 years ago • 0 comments

两种实现方式:代码见gist

contextlib这个库小而精, 可以实现很多功能,如回滚:

In [20]: @contextlib.contextmanager
   ....: def list_transaction(lis):
   ....:     working = list(lis)
   ....:     yield working
   ....:     lis[:] = working
   ....:

In [21]: item = [1,2,3]

In [22]: with list_transaction(item) as working:
   ....:     working.append(4)
   ....:     working.append(5)
   ....:     raise RuntimeError("oops")
   ....:
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-22-1d3397fb1866> in <module>()
      2     working.append(4)
      3     working.append(5)
----> 4     raise RuntimeError("oops")
      5

RuntimeError: oops

In [23]: item
Out[23]: [1, 2, 3]

在一个执行逻辑中当遇到异常则回滚。而平时使用的方式确实有修改就生效,直到抛出异常为止。

In [24]: for i in [4, 5]:
   ....:     item.append(i)
   ....:     raise RuntimeError("oops")
   ....:
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-24-14821b16e499> in <module>()
      1 for i in [4, 5]:
      2     item.append(i)
----> 3     raise RuntimeError("oops")
      4

RuntimeError: oops

In [25]: item
Out[25]: [1, 2, 3, 4]

但是其nested方法貌似有点多余了,不太简洁,如:

import contextlib

with contextlib.nested(open('a.py', 'rb'),
                       open('b.py', 'wb')) as (reader, writer):
    writer.write(reader.read())


with open('a.py', 'rb') as reader, \
        open('c.py', 'wb') as writer:
    writer.write(reader.read())

limboinf avatar Jul 08 '16 14:07 limboinf