是否有办法防止模块urllib3捕获KeyboardInterrupt?当KeyboardInterrupt发生时,我需要执行一些进程,但问题是urllib3模块似乎捕获异常而不传递它。
我写了一个示例脚本来演示我的问题。
connector.py
import requests
from time import sleep
class Connector:
def __init__(self):
pass
def connect(self):
try:
URL="https://www.gelbeseiten.de"
print("Connecting")
sleep(1)
print("Now")
requests.get(URL)
requests.get(URL)
requests.get(URL)
requests.get(URL)
except Exception as e:
print("Exception in connect")
raise Exception()
main.py
import connector
def main():
try:
conn=connector.Connector()
conn.connect()
except Exception as e:
print("Exception in main")
if __name__ == '__main__':
main()
如果脚本正在执行GET请求,我执行一个KeyboardInterrupt (Ctrl + C),我所期望的是第一个"Exception in connect"然后"Exception in main"但是我得到了以下输出
Traceback (most recent call last):
File "/tmp/test/main.py", line 11, in <module>
main()
File "/tmp/test/main.py", line 6, in main
conn.connect()
File "/tmp/test/connector.py", line 16, in connect
requests.get(URL)
File "/usr/lib/python3/dist-packages/requests/api.py", line 76, in get
return request('get', url, params=params, **kwargs)
File "/usr/lib/python3/dist-packages/requests/api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 428, in __exit__
self.close()
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 747, in close
v.close()
File "/usr/lib/python3/dist-packages/requests/adapters.py", line 325, in close
self.poolmanager.clear()
File "/usr/lib/python3/dist-packages/urllib3/poolmanager.py", line 222, in clear
self.pools.clear()
File "/usr/lib/python3/dist-packages/urllib3/_collections.py", line 100, in clear
self.dispose_func(value)
File "/usr/lib/python3/dist-packages/urllib3/poolmanager.py", line 173, in <lambda>
self.pools = RecentlyUsedContainer(num_pools, dispose_func=lambda p: p.close())
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 491, in close
if conn:
KeyboardInterrupt
这表明模块urllib3得到了中断信号,并没有将其传递给我的异常处理程序。它们是一种获得我预期行为的方法吗?
KeyboardInterrupt
不会被捕获。
异常当用户点击中断键(通常为Control-C或Delete)时引发。在执行过程中,定期检查中断。该异常继承自BaseException,以便不会被捕获exception的代码意外捕获,从而阻止解释器退出。
看到https://docs.python.org/3/library/exceptions.html KeyboardInterrupt
这里的问题是KeyboardInterrupt
不是Exception
的子类。如果您特别想捕获KeyboardInterrupt
,则必须使用except KeyboardInterrupt as e:
。
同时,最好使用raise e
而不是引发一个新的Exception
。
我认为你需要改变你的raise
脚本,因为KeyboardInterrupt
似乎不像继承自Exception
。相反,它来自BaseException
。请为您的connector.py
尝试以下代码。
import requests
from time import sleep
class Connector:
def __init__(self):
pass
def connect(self):
try:
URL="https://www.gelbeseiten.de"
print("Connecting")
sleep(1)
print("Now")
requests.get(URL)
requests.get(URL)
requests.get(URL)
requests.get(URL)
except Exception as e:
print("Exception in connect")
raise Exception()
except KeyboardInterrupt as e:
print("Keyboard interrupt")
raise Exception