【问题标题】:How to use contextmanagers for instance variables如何将上下文管理器用于实例变量
【发布时间】:2012-12-20 11:08:47
【问题描述】:

如何将 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 让我感到困惑。

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

【问题讨论】:

  • 对象销毁时间从来都不是处理任何事情的正确时间,尤其是资源管理。忘记有垃圾收集之类的东西,并假设所有对象都无限期地存在。

标签: python destructor with-statement


【解决方案1】:

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

__del__ 永远不值得。

【讨论】:

    【解决方案2】:
    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-30
      • 1970-01-01
      • 2011-05-15
      • 2013-04-11
      • 1970-01-01
      • 2014-02-04
      相关资源
      最近更新 更多