在python的自定义类中实现'with object() as f'的使用
Posted
技术标签:
【中文标题】在python的自定义类中实现\'with object() as f\'的使用【英文标题】:Implementing use of 'with object() as f' in custom class in python在python的自定义类中实现'with object() as f'的使用 【发布时间】:2011-04-16 00:24:41 【问题描述】:我必须在 python 中打开一个类似文件的对象(它是通过 /dev/ 的串行连接)然后关闭它。这在我班的几种方法中多次完成。我的做法是在构造函数中打开文件,然后在析构函数中关闭它。不过我遇到了一些奇怪的错误,我认为这与垃圾收集器等有关,我仍然不习惯不知道我的对象何时被删除=\
我这样做的原因是因为我每次打开它时都必须使用带有一堆参数的tcsetattr
,而且到处都这样做很烦人。所以我想实现一个内部类来处理所有这些,这样我就可以用它来做with Meter('/dev/ttyS2') as m:
我在网上找了一个关于with
语法是如何实现的很好的答案。我看到它使用了__enter__(self)
和__exit(self)__
方法。但是我所要做的就是实现这些方法并且我可以使用 with 语法吗?还是还有更多?
是否有关于如何执行此操作的示例或一些关于它如何在文件对象上实现的文档,我可以查看?
【问题讨论】:
【参考方案1】:第一个谷歌热门(对我来说)解释得很简单:
http://effbot.org/zone/python-with-statement.htm
PEP 解释得更准确(但也更冗长):
http://www.python.org/dev/peps/pep-0343/
【讨论】:
我实际上看到了这些,但认为它们中的任何一个都不是很清楚。第一个几乎说“有称为 _enter_ 和 _exit_ 的方法”并且几乎没有解释它们。 PEP 几乎只是在谈论对新语法的需求 不,通过示例和解释很简单。你需要再读一遍;这不是一个复杂的功能。 无论如何,您应该知道,仅链接的答案在整个社区中都很少被接受。至少从支持你的断言的来源分享一些东西。 第一个链接失效【参考方案2】:这些方法几乎是使对象与with
语句一起工作所需的全部。
在__enter__
中,您必须在打开并设置文件对象后返回它。
在__exit__
中,您必须关闭文件对象。写入它的代码将在with
语句体中。
class Meter():
def __init__(self, dev):
self.dev = dev
def __enter__(self):
#ttysetattr etc goes here before opening and returning the file object
self.fd = open(self.dev, MODE)
return self
def __exit__(self, type, value, traceback):
#Exception handling here
close(self.fd)
meter = Meter('dev/tty0')
with meter as m:
#here you work with the file object.
m.fd.read()
【讨论】:
def __enter__(self): return self
如果你想在 with 块中引用 Meter
。【参考方案3】:
最简单的可能是使用标准 Python 库模块contextlib:
import contextlib
@contextlib.contextmanager
def themeter(name):
theobj = Meter(name)
yield theobj
theobj.close() # or whatever you need to do at exit
这不会使Meter
本身成为上下文管理器(因此对那个类没有侵入性),而是“装饰”它(不是从 Python 的“装饰器语法”的意义上说,而是差不多,但是不完全是,在装饰器设计模式的意义上;-) 具有工厂函数themeter
,是一个上下文管理器(contextlib.contextmanager
装饰器从“single-yield
”构建您编写的生成器函数)- 这使得 so 更容易分离进入和退出条件,避免嵌套等。
【讨论】:
这比基于类的方法简单得多。 为了确保theobj.close()
即使在异常情况下也能执行,您可以用try...finally
块包装yield theobj
。以上是关于在python的自定义类中实现'with object() as f'的使用的主要内容,如果未能解决你的问题,请参考以下文章
csharp 通用检查器类,它允许您在类文件中而不是在单独的自定义编辑器中实现OnScene / InspectorGUI。它也提供