Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用`'调用`;s _u退出_u显式退出_Python_Python 2.7 - Fatal编程技术网

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