称之为'with`' s __exit__明确地退出

时间:2015-12-02 21:19:56

标签: python python-2.7

我的类在初始化时打开套接字连接,并且可以与交易对手来回传输和接收某些消息。我使用with语句创建对象的实例。在我的课程中,如果我在套接字上收到某些消息,我想显式关闭连接,并退出with语句。

我尝试通过明确调用self.\__exit__(None, None, None)

来实现此目的
def __exit__(self, type, value, traceback):
    print 'Closing Connection'
    self.logout()
    self.conn.close()
    sys.exit(1)

但是,我发现我收到Closing Connection消息两次,并遇到问题,因为在第二次调用时,不再有关闭的连接。检查代码,我排除了显式调用self.__exit__(None, None, None)的所有其他实例。发生了什么事? sys.exit(1)是否不足以阻止with再次收集垃圾(尽管从我所读过的内容来看,这似乎是最常见的"已批准的"这样做的方法) ?如何阻止with语句调用self.__exit__(None, None, None)。任何帮助,或正确方向的一点,将不胜感激!

2 个答案:

答案 0 :(得分:0)

进入with声明后,在不运行__exit__的情况下离开的唯一方法是使用os._exit;那很糟糕。相反,如果您想要这种行为,请通过调用__enter__显式开始。或者更改你的课程,以确保如果在他的回答中提到的两次,如@Kay所示,它不会进行两次清理。或者,正如@IsmailBadawi在评论中所做的那样,并重构您的代码,这样您就不需要明确调用__exit__

答案 1 :(得分:0)

只要记住你已经关闭了连接/日志/东西:

class MyContext(object):
    def __init__(self):
        self.__already_closed = False

    ....

    def close(self):
        if not self.__already_closed:
            self.__already_closed = True
            self.logout()
            self.conn.close()

    def __exit__(...):
        self.close()

甚至可以添加一个"请不要清理"方法:

    def do_not_cleanup(self):
        self.__already_closed = True