python 3.8 更新簡介
- 新的
:=
表達式 - Positional-only 函數參數
- 更易於調試的 f-string
- asyncio 在 windows 上默認使用 ProactorEventLoop 而不是之前的 SelectorEventLoop
- 等等
詳情參考 python3.8 官方文檔
安裝 jupyter 與 PyQt5
首先去 Unofficial Windows Binaries for Python Extension Packages 下載需要的 whl 包手動安裝 (因爲如果本地沒有這些包的編譯工具,pip 安裝過程中會報錯)
將以下包下載到本地之後:
- pywin32‑225‑cp38‑cp38‑win_amd64.whl
- pyzmq‑18.1.0‑cp38‑cp38‑win_amd64.whl
- pywinpty‑0.5.5‑cp38‑cp38‑win_amd64.whl
cmd 到文件下載目錄之後執行以下命令手動安裝:
pip install pywin32‑225‑cp38‑cp38‑win_amd64.whl pyzmq‑18.1.0‑cp38‑cp38‑win_amd64.whl pywinpty‑0.5.5‑cp38‑cp38‑win_amd64.whl
pip install -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com jupyter PyQt5
將 D:\Python3\Lib\site-packages\pywin32_system32
下的兩個文件,也就是 pythoncom38.dll
和 pywintypes38.dll
拷貝到 C:\Windows\System32
, 否則執行 jupyter-qtconsole.exe
將會報以下錯誤:
import win32api ImportError: DLL load failed: 找不到指定的模塊”
運行 jupyter-notebook
之後,會報以下錯誤:
C:\Python38\Scripts>jupyter-notebook.exe
Traceback (most recent call last):
File "c:\python38\lib\runpy.py", line 192, in _run_module_as_main
return _run_code(code, main_globals, None,
File "c:\python38\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Python38\Scripts\jupyter-notebook.exe\__main__.py", line 9, in <module>
File "c:\python38\lib\site-packages\jupyter_core\application.py", line 267, in launch_instance
return super(JupyterApp, cls).launch_instance(argv=argv, **kwargs)
File "c:\python38\lib\site-packages\traitlets\config\application.py", line 663, in launch_instance
app.initialize(argv)
File "<c:\python38\lib\site-packages\decorator.py:decorator-gen-7>", line 2, in initialize
File "c:\python38\lib\site-packages\traitlets\config\application.py", line 87, in catch_config_error
return method(app, *args, **kwargs)
File "c:\python38\lib\site-packages\notebook\notebookapp.py", line 1679, in initialize
self.init_webapp()
File "c:\python38\lib\site-packages\notebook\notebookapp.py", line 1442, in init_webapp
self.http_server.listen(port, self.ip)
File "c:\python38\lib\site-packages\tornado\tcpserver.py", line 152, in listen
self.add_sockets(sockets)
File "c:\python38\lib\site-packages\tornado\tcpserver.py", line 165, in add_sockets
self._handlers[sock.fileno()] = add_accept_handler(
File "c:\python38\lib\site-packages\tornado\netutil.py", line 279, in add_accept_handler
io_loop.add_handler(sock, accept_handler, IOLoop.READ)
File "c:\python38\lib\site-packages\tornado\platform\asyncio.py", line 99, in add_handler
self.asyncio_loop.add_reader(fd, self._handle_events, fd, IOLoop.READ)
File "c:\python38\lib\asyncio\events.py", line 501, in add_reader
raise NotImplementedError
NotImplementedError
是由於 python3.8 asyncio 在 windows 上默認使用 ProactorEventLoop 造成的,而不是之前的 SelectorEventLoop。jupyter 依賴 tornado,而 tornado 在 window 上需要使用 SelectorEventLoop,所以產生這個報錯
對於用戶自己寫的,依賴於 tornado 的程序,tornado 官方文檔已經說明:
On Windows, Tornado requires the ``WindowsSelectorEventLoop``. This is
the default in Python 3.7 and older, but Python 3.8 defaults to an
event loop that is not compatible with Tornado. Applications that use
Tornado on Windows with Python 3.8 must call
``asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())``
at the beginning of their ``main`` file/function.
而對於像 jupyter 這種依賴於 tornado 的庫,則無法用這種方式。目前這個問題已由 python 官方跟蹤:https://bugs.python.org/issue37373
臨時解決辦法:
修改 D:\Python3\Lib\site-packages\tornado\platform\asyncio.py
import asyncio
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
也就是在 import asyncio
之後,手動讓 tornado 選擇 SelectorEventLoop,這樣 jupyter 就可以正常使用了。
所以現在其實不太建議升級到 python3.8
相關 issue:
- https://github.com/tornadoweb/tornado/issues/2608
- https://github.com/jupyter/notebook/issues/4613