Python 如何对实例变量使用ContextManager

Python 如何对实例变量使用ContextManager,python,destructor,with-statement,Python,Destructor,With Statement,如何将Contextmanager用于实例变量?例如。 让我们假设我有一些连接类,它们必须在销毁时关闭。如果我作为ContextManager来实现它,我可以做到 with Connection() as c: c.write('FOO') c.ask('BAR?') 一旦被摧毁,它就会自动关闭。但是,如果我想在另一个类的\uuuu init\uuuu中使用它,比如下面的例子,该怎么办 class Device(object): def __init__(self):

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

with Connection() as c:
    c.write('FOO')
    c.ask('BAR?')
一旦被摧毁,它就会自动关闭。但是,如果我想在另一个类的
\uuuu init\uuuu
中使用它,比如下面的例子,该怎么办

class Device(object):
    def __init__(self):
        self.connection = Connection()  # Must be closed on destruction.
我不希望它在构造函数退出时关闭,它应该在对象被销毁时死亡。我可以使用
\uu del\uu
,但这有它的缺点。在C++中使用RAII会使我困惑。p>
那么,在这种情况下,最好的方法是什么呢?

您应该在
设备.close()方法中调用
self.connection.close
,然后安排在程序中正确调用它,也许可以使用上下文管理器


\uu del\uu
永远不值得

对象销毁时间对任何事情都不是合适的时间,特别是对资源管理来说。忘了垃圾收集之类的东西,假设所有对象都无限期地存在。
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)