python3.8 安裝 jupyter PyQt5

python 3.8 更新簡介

  1. 新的 := 表達式
  2. Positional-only 函數參數
  3. 更易於調試的 f-string
  4. asyncio 在 windows 上默認使用 ProactorEventLoop 而不是之前的 SelectorEventLoop
  5. 等等
    詳情參考 python3.8 官方文檔

安裝 jupyter 與 PyQt5

首先去 Unofficial Windows Binaries for Python Extension Packages 下載需要的 whl 包手動安裝 (因爲如果本地沒有這些包的編譯工具,pip 安裝過程中會報錯)
將以下包下載到本地之後:

  1. pywin32‑225‑cp38‑cp38‑win_amd64.whl
  2. pyzmq‑18.1.0‑cp38‑cp38‑win_amd64.whl
  3. 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.dllpywintypes38.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:

  1. https://github.com/tornadoweb/tornado/issues/2608
  2. https://github.com/jupyter/notebook/issues/4613
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章