4

我正在尝试在 Anaconda 3 中使用 Sage,但看起来这些库没有被导入。

我首先创建了一个新环境“ipykernel_py2”,然后按照此处的说明安装了 Python 2 。有了这个,我可以在 Anaconda 3 中启动并运行 Python 3 和 Python 3。

然后我转到创建的内核文件夹(C:\Users\YOUR_USERNAME\AppData\Local\Continuum\anaconda3\envs\ipykernel_py2\share\jupyter\kernels)并粘贴 Sage 的内核(取自 C:\Program Files\SageMath 8.2\运行时\opt\sagemath-8.2\local\share\jupyter\kernels)。这允许在 Jupyter 中创建新的 SageMath 文件,但内核已死。为了激活内核,我使用了 Anaconda Prompt 并输入:

activate ipykernel_py2
python -m ipykernel install --user --name sagemath --display-name "SageMath 8.2"

所以内核现在被激活,我可以创建和运行 Sage 文件。但是,图书馆仍然无法正常工作。该文件似乎像普通的 Python 2 文件一样运行。

有谁知道如何解决这一问题?我需要创建一个单独的环境吗?

4

1 回答 1

4

Sage for Windows 在名为 Cygwin 的 UNIX 仿真环境下运行。查看sagemath/kernel.json它包含:

{"display_name": "SageMath 8.2", "argv": ["/opt/sagemath-8.2/local/bin/sage", "--python", "-m", "sage.repl.ipython_kernel", "-f", "{connection_file}"]}

您可以在这里看到它有一个 UNIX 风格的sage可执行文件路径。该路径只对在 Sage 的 Cygwin 环境下运行的其他程序有意义,对原生 Windows 程序没有意义。简单地将其转换为等效的 Windows 路径也不起作用,因为bin/sage它实际上是一个 shell 脚本。至少您需要为Cygwin提供一个Windows路径,并将其传递给可执行文件的UNIX路径(与上面的相同)。如果没有登录 shell,也不会设置所需的大多数环境变量,因此您可能需要.bashsagebash -l

所以,像:

{"display_name": "SageMath 8.2", "argv": ["C:\\Program Files\\SageMath 8.2\\runtime\\bin\\bash.exe", "-l", "/opt/sagemath-8.2/local/bin/sage", "--python", "-m", "sage.repl.ipython_kernel", "-f", "{connection_file}"]}

可能工作。我不确定的一件事是这个{connection_file}论点是否也能得到妥善处理。我没有测试过。

更新:确实,上述部分有效,但存在一些问题:{connection_file}参数作为文件的绝对 Windows 路径传递。虽然 Cygwin 通常可以透明地从 Windows 路径转换为相应的 UNIX 路径,但有一个已知问题是 Cygwin 上的 Pythonos.path模块不能很好地处理 Windows 样式的路径,这会导致问题。

我遇到的另一个主要问题是IPKernelApp,驱动通用 Jupyter 内核的类有一个线程来轮询内核的父进程(在本例中为笔记本服务器)是否已退出,因此如果父进程关闭,它可以适当地关闭下。这就是内核知道在您终止笔记本服务器时自动关闭的方式。

这是如何完成的,取决于平台——Windows 与类 UNIX 的不同。因为 Sage 的内核在 Cygwin 中运行,所以它选择了类 UNIX 轮询器。但是,如果笔记本服务器恰好是本机 Windows 进程,则这是错误的,例如在 Windows 本机 Jupyter 中运行 Sage 内核时。值得注意的是,Windows 的父轮询器 可以在 Cygwin 上正常工作,因为它通过ctypes. 因此,可以通过为IPKernelApp强制使用ParentPollerWindows.

一个可能的解决方案看起来像这样:在 SageMath Shell 中执行以下操作:

$ cd "$SAGE_LOCAL"
$ mkdir -p ./share/jupyter/kernels/sagemath
$ cd ./share/jupyter/kernels/sagemath
$ cat <<_EOF_ > kernel-wrapper.sh
#!/bin/sh
here="$(dirname "$0")"
connection_file="$(cygpath -u -a "$1")"
exec /opt/sagemath-8.2/local/bin/sage --python "${here}/kernel-wrapper.py" -f "${connection_file}"
_EOF_
$ cat <<_EOF_ > kernel-wrapper.py
from ipykernel.kernelapp import IPKernelApp as OrigIPKernelApp
from ipykernel.parentpoller import ParentPollerWindows
from sage.repl.ipython_kernel.kernel import SageKernel


class IPKernelApp(OrigIPKernelApp):
    """
    Although this kernel runs under Cygwin, its parent is a native Windows
    process, so we force use of the ParentPollerWindows.
    """

    def init_poller(self):
        if self.interrupt or self.parent_handle:
            self.poller = ParentPollerWindows(self.interrupt,
                                              self.parent_handle)


IPKernelApp.launch_instance(kernel_class=SageKernel)
_EOF_

现在编辑kernel.json(在其现有位置下share\jupyter\kernels\sagemath)阅读:

{"display_name": "SageMath 8.2", "argv": ["C:\\Program Files\\SageMath 8.2\\runtime\\bin\\bash.exe", "-l", "/opt/sagemath-8.2/local/share/jupyter/kernels/sagemath/kernel-wrapper.sh", "{connection_file}"]}

这运行kernel-wrapper.sh,而后者又运行kernel-wrapper.py。(我可以做一些简化来完全摆脱对的需求,但在包含PyCygwinkernel-wrapper.sh的 SageMath 8.3 中这会更容易。)

确保将每个“8.2”更改为适合您 Sage 安装的“XY”版本。

更新:感谢用户的反馈,进行了一些更新,但我尚未测试这些更改,因此请确保我的说明中的每个文件/目录路径都存在并且看起来正确,而不是盲目复制/粘贴。

正如你所看到的,这不是微不足道的,而且从设计上来说从来都不是可能的。但这是可以完成的。一旦内核本身启动并运行,它只需通过 TCP/IP 套接字与其通信,因此之后不会涉及太多魔法。我相信在 Jupyter 方面和 Sage 方面都可以进行一些小的改进,这将促进未来的这种事情......

于 2018-07-12T15:03:24.313 回答