我必须在Python中打开一个类似文件的对象(这是通过 /dev /的串行连接),然后将其关闭。这是我班级的几种方法多次完成的。我的操作方式是打开构造函数中的文件,然后在灾难中将其关闭。我虽然遇到了奇怪的错误,但我认为这与垃圾收集器有关,因此,我仍然不习惯确切知道何时删除我的对象=

我这样做的原因是因为我必须使用 tcsetattr 每次我打开它时,都会有一堆参数,并且在整个地方都会感到烦人。因此,我想实现一个内部类来处理所有这些,以便我可以使用它
with Meter('/dev/ttyS2') as m:

我在网上寻找,我找不到关于如何 with 语法已实现。我看到它使用了 __enter__(self)__exit(self)__ 方法。但是,我只需要实现这些方法,并且可以使用语法?还是还有更多?

是否有一个有关如何执行此操作的示例,或者有一些文档有关如何在文件对象上实现的文档?

有帮助吗?

解决方案

这些方法几乎是您使对象使用的所有需要 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.fd
    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.read()

其他提示

最简单的可能是使用标准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的“ Decorator Syntax”的意义;-)带有工厂功能 themeter 哪一个 上下文管理器( contextlib.contextmanager 装饰器从“单一”建造yield“您编写的发电机函数) - 这使得 所以 将进入和退出条件分开要容易得多,避免筑巢,&c。

第一个Google Hit(对我来说)就足够解释了:

http://effbot.org/zone/python-with-statement.htm

PEP更精确地解释了这一点(但更详细):

http://www.python.org/dev/peps/pep-0343/

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top