如何使用contextmanagers作为实例变量

时间:2013-01-06 15:50:08

标签: python destructor with-statement

如何将Contextmanager用于实例变量?例如。 我们假设我有一些Connection类,必须在销毁时关闭。如果我将它作为ContextManager实现,我可以做到。

with Connection() as c:
    c.write('FOO')
    c.ask('BAR?')

它将在销毁时自动关闭。但是如果我想在另一个类的__init__中使用它,例如如下例所示?

class Device(object):
    def __init__(self):
        self.connection = Connection()  # Must be closed on destruction.

我不希望它在构造函数退出时关闭,它会在对象被破坏时死掉。我可以使用__del__,但这有它的缺点。习惯于在C ++中使用RAII它让我感到困惑。

那么在这种情况下最好的方法是什么?

2 个答案:

答案 0 :(得分:6)

您应该在self.connection.close方法中调用Device.close(),然后安排在您的程序中正确调用它,可能使用上下文管理器。

__del__永远不值得。

答案 1 :(得分:1)

from contextlib import contextmanager

@contextmanager
def connection():
    conn = Conn()
    try:
        yield conn
    finally:
        conn.close()

class Conn(object):
    def close(self):
        print('Closing')

class Device(object):
    def __init__(self, conn):
        self.conn = Conn()

with connection() as conn:
    d = Device(conn)