1. 程式人生 > >python用from gevent import monkey; monkey.patch_all()之後報ssl等錯誤

python用from gevent import monkey; monkey.patch_all()之後報ssl等錯誤

  樓主今天第一次用python基於greenlet實現的第三方協程庫gevent,由於gevent在切換IO操作(檔案IO、網路IO)時是自動完成的,所以gevent需要通過修改Python自帶的一些阻塞式系統呼叫的標準庫,包括socket、ssl、threading和 select等模組,而變為協程,這一過程需要在啟動時通過monkey patch完成。

import gevent
from gevent import monkey
monkey.patch_all()

  樓主遇到的報錯如下(簡略版,只保留了前半部分報錯內容):

Traceback (most recent call last):
File 
"/usr/local/python3.6/lib/python3.6/site-packages/gevent/greenlet.py", line 536, in run result = self._run(*self.args, **self.kwargs) File "test.py", line 14, in req res = requests.get(url) File "/usr/local/python3.6/lib/python3.6/site-packages/requests/api.py", line 72, in get return request('get', url, params=params, **kwargs) File
"/usr/local/python3.6/lib/python3.6/ssl.py", line 459, in options super(SSLContext, SSLContext).options.set(self, value) [Previous line repeated 316 more times]

解決方案:

  仔細閱讀官方文件發現有這樣一段Tip:

Tip: 
When monkey patching, it is recommended to do so as early as possible in the lifetime of the process. 
If possible, monkey patching should be the first lines executed.
Monkey patching later, especially
if native threads have been created, atexit or signal handlers have been installed, or sockets have been created,
may lead to unpredictable results including unexpected LoopExit errors.

即,monkey patching需要放到第一行匯入,否則會報錯,所以,把 from gevent import monkey;monkey.patch_all() 放到檔案最前面就好啦

注:

  1、monkey patching 官方文件地址

  2、如果你用的python3.6,推薦使用asyncio