Python 用`'调用`;s _u退出_u显式退出
我有一个类,它在初始化时打开一个套接字连接,可以和对方来回发送和接收某些消息。我使用Python 用`'调用`;s _u退出_u显式退出,python,python-2.7,Python,Python 2.7,我有一个类,它在初始化时打开一个套接字连接,可以和对方来回发送和接收某些消息。我使用with语句创建对象的实例。在我的类中,如果我在套接字上收到某些消息,我希望显式地关闭连接,并退出带有语句的 我试图通过显式调用self.\\uu退出(None,None,None) 但是,我发现我收到了两次关闭连接消息,并且遇到了问题,因为在第二次呼叫中,不再有要关闭的连接。检查代码时,我排除了显式调用self的所有其他实例。发生什么事?sys.exit(1)是否不足以防止with再次进行垃圾收集(尽管从我所读
with
语句创建对象的实例。在我的类中,如果我在套接字上收到某些消息,我希望显式地关闭连接,并退出带有语句的
我试图通过显式调用self.\\uu退出(None,None,None)
但是,我发现我收到了两次关闭连接
消息,并且遇到了问题,因为在第二次呼叫中,不再有要关闭的连接。检查代码时,我排除了显式调用self的所有其他实例。发生什么事?sys.exit(1)
是否不足以防止with
再次进行垃圾收集(尽管从我所读的内容来看,这似乎是最“认可”的方法)?如何防止with
语句调用self.\uuu\uu退出(无,无,无)
。任何帮助,或在正确的方向上的一点,将不胜感激 一旦进入with
语句,离开with而不运行\uuuuuuuuuuuu
的唯一方法就是使用os.\u exit
;那太糟糕了。相反,如果需要此行为,请显式地从调用\uuuuu enter\uuuu
开始。或者改变你的类,确保它不会像@Kay在回答中建议的那样,在被调用两次时进行两次清理。或者,按照@IsmailBadawi在其评论中的建议执行,重构代码,这样您就不需要显式调用\uuuuu exit\uuuu
只要记住您是否已经关闭了连接/log/什么:
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()
甚至可以添加一个“请不要清理”方法:
当控制流使用
语句离开时,将始终调用\uuuuuu退出
方法,无论这种情况如何发生。你不应该明确地称呼它。如果你重新构造了你的代码,这样你就不需要这样做了,那就更好了。另外,在\uuuuuuuuuuuuuuuuu
函数中使用sys.exit(1)
也是不好的形式<代码>\uuuu退出\uuuu
函数应仅抑制异常或允许它们通过;他们不应该退出程序,因为他们只是为了清理或资源管理。它隐藏了程序逻辑,使代码难以阅读。使用
语句从顶级的运行sys.exit(1)
,这样就可以清楚地看到您退出时有一个错误值。不要显式调用\uuuuuuuuexit()\uuuuuuuuuuu
,那么就没有问题了。您可以从上下文管理器内部返回,也可以从末尾掉下来:这就是应该如何调用\uuuuuu exit()\uuuuu
。@eestrada,您能解释一下“从顶层
中运行sys.exit(1)并使用'statement'”是什么意思吗?@amid:是的,尽管我不能在注释中使用换行符,这可能有点难读。因此,与其使用mycontext()作为mc:if problem:mc.\uuuu exit\uuuu(None,None,None)
执行,并让sys.exit(1)
在\uu exit\uuuu
函数中运行,不如使用mycontext()作为mc:if problem:sys.exit(1)
执行,并明确说明您试图在失败时退出。您的\uuuuuuuuuuuuuuuu退出
函数将被调用,无论您如何使用语句(异常、退出、结束下降、早期返回
等)。当您说“显式地通过调用\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu进入””开始时,您的意思是不将与语句一起使用吗?因此,创建对象。然后调用obj.\uuuuu enter\uuuuuu()
?@amid:是的,这确实是我显式调用\uuuuuuuu enter\uuuuuuuuu
的意思。然而,这不是你通常应该做的事情。我唯一一次这样做是作为单元测试中设置
/拆卸
的一部分(即使是在没有其他选项的情况下)。否则,让with
语句为您完成有关何时调用\uuuuuuuuuuuu进入
和\uuuuuuu退出
函数的工作。您需要担心的是,如果您的\uuuuuuu exit\uuuu
函数需要处理异常,它将如何处理异常。
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