[英]How do I define a Python class that I can use with the with statement?
I understand that StringIO
acts like a file object, duck-typing what you would get from open('somefile.txt')
. 我知道
StringIO
就像一个文件对象,可以open('somefile.txt')
你从open('somefile.txt')
。
Now I want to use StringIO
with the with
statement: 现在我想使用带有
with
语句的StringIO
:
with StringIO('some string') as fh: # fh as in "file handle"
data = [stuff from stuff in fh.read()]
But Python complains that type StringIO
does not have an __exit__
method. 但Python抱怨
StringIO
类型没有__exit__
方法。 After subclassing StringIO
: StringIO
:
class MyStringIO(StringIO):
def __exit__(self):
self.close()
I now get an exception about not having an __enter__
method. 我现在得到一个关于没有
__enter__
方法的例外。 How do I define the __enter__
method? 如何定义
__enter__
方法? What does Python expect from a class that can be used with the with
statement? Python对可以与
with
语句一起使用的类有什么期望?
You need to write a context manager . 您需要编写上下文管理器 。 If you don't want to write the whole protocol, there's a simplified way around it using the contextlib.contextmanager decorator.
如果您不想编写整个协议,可以使用contextlib.contextmanager装饰器简化它。
Just to give an example where it would be overkill do use contextlib, which is more for use with generators: 只是举一个例子来说它是矫枉过正的,请使用contextlib,它更适用于生成器:
Here is a nice and useful example of a context manager. 这是一个很好的有用的上下文管理器示例。 I found it in David Beazley's blog:
我在David Beazley的博客中找到了它:
http://dabeaz.blogspot.de/2010/02/context-manager-for-timing-benchmarks.html http://dabeaz.blogspot.de/2010/02/context-manager-for-timing-benchmarks.html
and just modified it a little bit to use the best timer per platform, a trick that I use from the timeit module: 并且只是稍微修改它以使用每个平台的最佳计时器,这是我在timeit模块中使用的技巧:
# benchmark.py
import timeit
class benchmark(object):
from timeit import default_timer as timer
def __init__(self, name):
self.name = name
def __enter__(self):
self.start = self.timer()
def __exit__(self, ty, val, tb):
end = self.timer()
print("%s : %0.3f seconds" % (self.name, end-self.start))
return False
Now that gives you a context manager that you can use like this: 现在,它为您提供了一个上下文管理器,您可以像这样使用:
with benchmark('algorithm 1'):
... (some computation)
with benchmark('other approach'):
... (some other computation)
and you get your output printed. 并打印出你的输出。 I liked this example and wanted to share it.
我喜欢这个例子,想分享它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.