gpt4 book ai didi

python - 当你抛出异常时,Python 对象会发生什么

转载 作者:行者123 更新时间:2023-11-28 21:30:47 27 4
gpt4 key购买 nike

我的类包含一个连接到服务器的套接字。该类的某些方法可能会引发异常。我正在运行的脚本包含一个外部循环,该循环捕获异常、记录错误并创建一个尝试重新连接到服务器的新类实例。

问题是服务器一次仅处理一个连接(根据设计),并且“旧”套接字仍然处于连接状态。因此,新的连接尝试会挂起脚本。我可以通过强制关闭旧套接字来解决这个问题,但我想知道:为什么套接字不自动关闭?

当它“卡住”时,netstat 显示连接到该端口的两个套接字。服务器正在等待来自第一个套接字的输入,但尚未处理新的套接字。

我在虚拟服务器上运行此命令,该服务器向每个传入线路回复“错误\n”。

编辑:请参阅我对 Mark Rushakoff's answer below 的评论。异常处理程序中的断言(False)[我随后捕获]似乎强制关闭套接字。

import socket

class MyException(Exception):
pass

class MyClient(object):

def __init__(self, port):
self.sock = socket.create_connection(('localhost', port))
self.sockfile = self.sock.makefile()

def do_stuff(self):
self._send("do_stuff\n")
response = self._receive()
if response != "ok\n":
raise MyException()
return response

def _send(self, cmd):
self.sockfile.write(cmd)
self.sockfile.flush()

def _receive(self):
return self.sockfile.readline()

def connect():
c = MyClient(9989)
# On the second iteration, do_stuff() tries to send data and
# hangs indefinitely.
print c.do_stuff()

if __name__ == '__main__':
for _ in xrange(3):
try:
connect()
except MyException, e:
print 'Caught:', e
# This would be the workaround if I had access to the
# MyClient object:
#c.sock.close()
#c.sockfile.close()

编辑:这是(丑陋的)服务器代码:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
s.bind(('localhost', 9989))
s.listen(5)
(c,a) = s.accept()
f = c.makefile()
print f.readline()
f.write('error\n')
f.flush()
(c2,a) = s.accept()
f = c.makefile()
print f.readline()
s.close()

最佳答案

这是垃圾收集的产物。即使对象超出范围,它也不一定被收集,因此被销毁,直到发生垃圾收集运行 - 这与C++,一旦对象失去作用域,就会调用析构函数。

您可以通过将 connect 更改为

来解决此特定问题
def connect():
try:
c = MyClient(9989)
# On the second iteration, do_stuff() tries to send data and
# hangs indefinitely.
print c.do_stuff()
finally:
c.sock.close()
c.sockfile.close()

或者,您可以为 MyClient 定义 __enter____exit__,然后执行 a with statement :

def connect():
with MyClient(9989) as c:
print c.do_stuff()

这实际上与 try-finally 相同。

关于python - 当你抛出异常时,Python 对象会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1475193/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com