Path: blob/develop/src/doc/zh/tutorial/interactive_shell.rst
4086 views
.. _chapter-interactive_shell: ************ 交互式 Shell ************ 在本教程的大部分内容中,我们假定你使用 ``sage`` 命令启动 Sage 解释器。 这将启动一个定制版的 IPython Shell,并导入许多函数和类,使它们可以直接从命令提示符使用。 可以通过编辑 ``$SAGE_ROOT/ipythonrc`` 文件进行进一步的自定义。 启动 Sage 后,会输出以下类似内容: .. CODE-BLOCK:: text ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: 要退出 Sage 只需按 Ctrl-D 或输入 ``quit`` 或 ``exit``。 .. skip :: sage: quit Exiting Sage (CPU time 0m0.00s, Wall time 0m0.89s) Wall time 指的是墙上的挂钟走过的时间。因为 CPU 时间不会跟踪子进程(如 GAP 或 Singular)消耗的时间。 (请避免在终端中使用 ``kill -9`` 杀死 Sage 进程, 因为 Sage 可能无法终止子进程,例如 Maple 进程,或清理 ``$HOME/.sage/tmp`` 中的临时文件。) Sage 会话 ========= 会话是从 Sage 启动到退出期间的输入输出序列。Sage 通过IPython 记录所有 Sage 输入。 实际上,如果你使用的是交互式 Shell(而不是 notebook 界面), 你可以随时输入 ``%history`` (或 ``%hist``)来列出迄今为止输入的所有命令行。 在 Sage 提示符下输入 ``?`` 可以了解有关 IPython 的更多信息,例如, “IPython 提供带编号的提示符...并缓存输入和输出。所有输入都会保存, 并且可以作为变量检索(除了常用的箭头键召回外)。以下全局变量始终存在(所以不要覆盖它们!)”: .. CODE-BLOCK:: text _: 上一次输入 (交互式 SHell 和 notebook 均适用) __: 上两次输入 (仅交互式 Shell 适用) _oh : 所有输入的列表 (仅交互式 Shell 适用) 例如: .. skip :: sage: factor(100) _1 = 2^2 * 5^2 sage: kronecker_symbol(3,5) _2 = -1 sage: %hist # This only works from the interactive shell, not the notebook. 1: factor(100) 2: kronecker_symbol(3,5) 3: %hist sage: _oh _4 = {1: 2^2 * 5^2, 2: -1} sage: _i1 _5 = 'factor(ZZ(100))\n' sage: eval(_i1) _6 = 2^2 * 5^2 sage: %hist 1: factor(100) 2: kronecker_symbol(3,5) 3: %hist 4: _oh 5: _i1 6: eval(_i1) 7: %hist 我们在本教程和其他 Sage 文档中均省略了输出编号。 你还可以在会话中将输入列表储存在宏中。 .. skip :: sage: E = EllipticCurve([1,2,3,4,5]) sage: M = ModularSymbols(37) sage: %hist 1: E = EllipticCurve([1,2,3,4,5]) 2: M = ModularSymbols(37) 3: %hist sage: %macro em 1-2 Macro `em` created. To execute, type its name (without quotes). .. skip :: sage: E Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field sage: E = 5 sage: M = None sage: em Executing Macro... sage: E Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field 在使用交互式 Shell 时,任何 UNIX Shell 命令都可以通过在 Sage 前面加上感叹号 ``!`` 来执行。例如: .. skip :: sage: !ls auto example.sage glossary.tex t tmp tut.log tut.tex 返回当前目录的列表。 ``PATH`` 变量将 Sage 的 bin 目录放在最前端, 因此如果运行 ``gp``, ``gap``, ``singular``, ``maxima`` 等等,你会得到随 Sage 附带的版本。 .. skip :: sage: !gp Reading GPRC: /etc/gprc ...Done. GP/PARI CALCULATOR Version 2.2.11 (alpha) i686 running linux (ix86/GMP-4.1.4 kernel) 32-bit version ... sage: !singular SINGULAR / Development A Computer Algebra System for Polynomial Computations / version 3-0-1 0< by: G.-M. Greuel, G. Pfister, H. Schoenemann \ October 2005 FB Mathematik der Universitaet, D-67653 Kaiserslautern \ 记录输入和输出 ============== 记录 Sage 会话不同于保存会话(参见 :ref:`section-save`)。 要记录输入(和可选输出),请使用 ``logstart`` 命令。输入 ``logstart?`` 了解更多详情。 你可以使用这个命令记录你输入的所有内容、所有输出,甚至可以在未来的会话中重现输入(通过重新加载日志文件)。 .. skip .. CODE-BLOCK:: shell-session was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: logstart setup Activating auto-logging. Current session state plus future input saved. Filename : setup Mode : backup Output logging : False Timestamping : False State : active sage: E = EllipticCurve([1,2,3,4,5]).minimal_model() sage: F = QQ^3 sage: x,y = QQ['x,y'].gens() sage: G = E.gens() sage: Exiting Sage (CPU time 0m0.61s, Wall time 0m50.39s). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: load("setup") Loading log file <setup> one line at a time... Finished replaying log file <setup> sage: E Elliptic Curve defined by y^2 + x*y = x^3 - x^2 + 4*x + 3 over Rational Field sage: x*y x*y sage: G [(2 : 3 : 1)] 如果你在 Linux KDE 终端 ``konsole`` 中使用 Sage,那么可以按照以下步骤保存会话: 在 ``konsole`` 中启动 Sage 后,选择“设置”,然后“历史记录...”,然后“设置为无限制”。 当你准备保存会话时,选择“编辑”,然后“保存历史记录为...”,并输入一个名称将会话的文本保存到你的计算机。 保存这个文件后,你可以将其加载到编辑器(例如 xemacs)并打印出来。 粘贴忽略提示符 ============== 假设你正在阅读 Sage 或 Python 计算的会话,并希望将它们复制到 Sage 中。 但是有 ``>>>`` 或 ``sage:`` 提示符很烦人。实际上,你可以将包含提示符的示例复制并粘贴到 Sage 中。 换句话说,默认情况下,Sage 解析器在传递给 Python 之前会删除任何前导 ``>>>`` 或 ``sage:`` 提示符。例如: .. skip :: sage: 2^10 1024 sage: sage: sage: 2^10 1024 sage: >>> 2^10 1024 命令计时 ======== 如果你在输入的开头放置 ``%time`` 命令,那么命令执行的时间将显示在输出后。 例如,我们可以比较几种幂运算的运行时间。 这些计时在你电脑上可能会有很大不同,甚至在不同版本的 Sage 之间也会有所不同。 首先是原生 Python: .. skip :: sage: %time a = int(1938)^int(99484) CPU times: user 0.66 s, sys: 0.00 s, total: 0.66 s Wall time: 0.66 这意味着总共耗时 0.66 秒,"Wall time" 即墙上挂钟的时间为 0.66 秒。 如果你的计算机负载较重,wall time 可能比 CPU 时间长很多。 还可以使用 ``timeit`` 函数来尝试在大量迭代命令下获取时间。 这提供了稍微不同的信息,并且需要输入命令字符串来计时。 .. skip :: sage: timeit("int(1938)^int(99484)") 5 loops, best of 3: 44.8 ms per loop 接下来我们使用原生 Sage Integer 类型,它是用 Cython 调用 GMP 库实现的: .. skip :: sage: %time a = 1938^99484 CPU times: user 0.04 s, sys: 0.00 s, total: 0.04 s Wall time: 0.04 使用 PARI 的 C 语言接口: .. skip :: sage: %time a = pari(1938)^pari(99484) CPU times: user 0.05 s, sys: 0.00 s, total: 0.05 s Wall time: 0.05 GMP 表现稍好(预料之中,因为为 Sage 构建的 PARI 版本使用 GMP 进行整数运算)。 还可以使用 ``cputime`` 命令计时一组命令块,如下所示: :: sage: t = cputime() sage: a = int(1938)^int(99484) sage: b = 1938^99484 sage: c = pari(1938)^pari(99484) sage: cputime(t) # somewhat random output 0.64 .. skip :: sage: cputime? ... Return the time in CPU second since Sage started, or with optional argument t, return the time since time t. INPUT: t -- (optional) float, time in CPU seconds OUTPUT: float -- time in CPU seconds ``walltime`` 命令的行为与 ``cputime`` 命令类似,只是它计算的是挂钟时间。 我们也可以用 Sage 包含的计算机代数系统计算上面的幂。以下每种情况下,我们执行一个简单命令以启动该程序的服务器。 最相关的时间是挂钟时间。然而,如果挂钟时间和 CPU 时间之间存在显著差异,则可能表明存在值得优化的性能问题。 .. skip :: sage: time 1938^99484; CPU times: user 0.01 s, sys: 0.00 s, total: 0.01 s Wall time: 0.01 sage: gp(0) 0 sage: time g = gp('1938^99484') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 0.04 sage: maxima(0) 0 sage: time g = maxima('1938^99484') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 0.30 sage: kash(0) 0 sage: time g = kash('1938^99484') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 0.04 sage: mathematica(0) 0 sage: time g = mathematica('1938^99484') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 0.03 sage: maple(0) 0 sage: time g = maple('1938^99484') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 0.11 sage: libgap(0) 0 sage: time g = libgap.eval('1938^99484;') CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 1.02 注意,在这项测试中 GAP 和 Maxima 最慢(运行在 ``sage.math.washington.edu`` 机器上)。 由于 pexpect 接口的开销,将它们与最快的 Sage 相比可能不太公平。 其他 IPython 技巧 ================= 如上文所述,Sage 使用 IPython 作为前端,因此你可以使用任何 IPython 的命令和功能。 你可以阅读 `完整的 IPython 文档 <http://ipython.scipy.org/moin/Documentation>`_ 。 下面是一些有趣的技巧 -- 在 IPython 中,这些被称为 "Magic 命令": - 如果你想输入一些复杂代码,可以使用 ``%edit`` (或 ``%ed`` 或 ``ed``)打开一个编辑器。 在启动 Sage 之前,请确保 :envvar:`EDITOR` 环境变量设置为你喜欢的编辑器 (通过在适当位置如 ``.profile`` 文件中放置 ``export EDITOR=/usr/bin/emacs`` 或 ``export EDITOR=/usr/bin/vim`` 等)。在 Sage 提示符下执行 ``%edit`` 会打开指定的编辑器。 然后在编辑器中你可以定义一个函数: .. CODE-BLOCK:: python def some_function(n): return n**2 + 3*n + 2 保存并退出编辑器。在剩下的 Sage 会话期间,你可以使用 ``some_function``。 如果你想修改它,可以在 Sage 提示符下输入 ``%edit some_function``。 - 如果你有一个计算,并且想修改其输出以便用于其他用途,可执行计算并输入 ``%rep``: 这会将上一个命令的输出放置到 Sage 提示符,供你编辑。:: sage: f(x) = cos(x) sage: f(x).derivative(x) -sin(x) 此时如果你在 Sage 提示符下输入 ``%rep``, 你会得到一个新的 Sage 提示符,后面跟着 ``-sin(x)``, 光标在行尾。 要了解更多信息,请输入 ``%quickref`` 以获得 IPython 快速参考指南。 截止本文撰写时间(2011 年 4 月),Sage 使用的 IPython 版本为 0.9.1, `Magic 命令文档 <http://ipython.org/ipython-doc/dev/interactive/tutorial.html#magic-functions>`_ 可以在线访问。各种较为高级的 Magic 命令系统的内容记载在 `这里 <http://ipython.org/ipython-doc/stable/interactive/reference.html#magic-command-system>`_ 。 错误与异常 ========== 出现问题时,通常会看到 Python “异常”。Python 甚至会尝试给出引发异常的原因。 通常可以看到异常的名称,例如::class:`NameError` 或 :class:`ValueError` (详细异常列表请参见 Python 库参考 [PyLR]_ )。例如: .. skip :: sage: 3_2 ------------------------------------------------------------ File "<console>", line 1 ZZ(3)_2 ^ SyntaxError: invalid ... sage: EllipticCurve([0,infinity]) ------------------------------------------------------------ Traceback (most recent call last): ... TypeError: Unable to coerce Infinity (<class 'sage...Infinity'>) to Rational 有时交互式调试器对理解问题很有用。可以使用 ``%pdb`` 切换它(默认是关闭的)。 如果打开调试器,出现异常时会出现提示符 ``ipdb>``。在调试器中,可以打印任意局部变量的状态, 并在执行栈中上下移动。例如: .. skip :: sage: %pdb Automatic pdb calling has been turned ON sage: EllipticCurve([1,infinity]) --------------------------------------------------------------------------- <class 'exceptions.TypeError'> Traceback (most recent call last) ... ipdb> 在 ``ipdb>`` 提示符下输入 ``?`` 以获取调试器命令列表: .. CODE-BLOCK:: text ipdb> ? Documented commands (type help <topic>): ======================================== EOF break commands debug h l pdef quit tbreak a bt condition disable help list pdoc r u alias c cont down ignore n pinfo return unalias args cl continue enable j next pp s up b clear d exit jump p q step w whatis where Miscellaneous help topics: ========================== exec pdb Undocumented commands: ====================== retval rv 输入 Ctrl-D 或 ``quit`` 返回 Sage。 .. _section-tabcompletion: 反向搜索与 Tab 补全 =================== 反向搜索: 输入命令的开头,然后按 ``Ctrl-p`` (或直接按上箭头键)查看以前输入的以该命令开头的命令行。 即使你完全退出 Sage 并稍后重新启动,这些功能仍然可以使用。也可以使用 ``Ctrl-r`` 通过历史记录进行反向搜索。 所有这些功能均使用 ``readline`` 软件包,可在大多数 Linux 版本中使用。 为了演示 Tab 补全,首先创建三维向量空间 `V=\QQ^3` 如下: :: sage: V = VectorSpace(QQ,3) sage: V Vector space of dimension 3 over Rational Field 也可以使用如下更简洁的表示法: :: sage: V = QQ^3 然后可以很容易地使用 Tab 补全列出 `V` 的所有成员函数。只需输入 ``V.``, 然后按键盘上的 :kbd:`Tab` 键: .. skip :: sage: V.[tab key] V._VectorSpace_generic__base_field ... V.ambient_space V.base_field V.base_ring V.basis V.coordinates ... V.zero_vector 如果输入函数的前几个字母,然后按 :kbd:`Tab` 键,只会显示以这些字母开头的函数。 .. skip :: sage: V.i[tab key] V.is_ambient V.is_dense V.is_full V.is_sparse 如果想知道某函数的作用,例如 coordinates 函数, 输入 ``V.coordinates?`` 来获取帮助或 ``V.coordinates??`` 查看源码,如下一节所述。 集成帮助系统 ============ Sage 拥有集成帮助系统。输入函数名后跟 ? 可以查看该函数的文档。 .. skip :: sage: V = QQ^3 sage: V.coordinates? Type: instancemethod Base Class: <class 'instancemethod'> String Form: <bound method FreeModule_ambient_field.coordinates of Vector space of dimension 3 over Rational Field> Namespace: Interactive File: /home/was/s/local/lib/python2.4/site-packages/sage/modules/f ree_module.py Definition: V.coordinates(self, v) Docstring: Write v in terms of the basis for self. Returns a list c such that if B is the basis for self, then sum c_i B_i = v. If v is not in self, raises an ArithmeticError exception. EXAMPLES: sage: M = FreeModule(IntegerRing(), 2); M0,M1=M.gens() sage: W = M.submodule([M0 + M1, M0 - 2*M1]) sage: W.coordinates(2*M0-M1) [2, -1] 如上所示,输出告诉你对象的类型,定义它的文件,以及有用的函数描述及示例, 可以将这些示例粘贴到当前会话中。几乎所有这些示例都会定期自动测试,以确保它们正常工作并完全按照描述运行。 另一个非常符合 Sage 开源精神的功能是,如果 ``f`` 是一个 Python 函数, 那么输入 ``f??`` 会显示定义 ``f`` 的源代码。例如: .. skip :: sage: V = QQ^3 sage: V.coordinates?? Type: instancemethod ... Source: def coordinates(self, v): """ Write $v$ in terms of the basis for self. ... """ return self.coordinate_vector(v).list() 这告诉我们 ``coordinates`` 函数所做的就是调用 ``coordinate_vector`` 函数并将结果转换为列表。 ``coordinate_vector`` 函数做什么? .. skip :: sage: V = QQ^3 sage: V.coordinate_vector?? ... def coordinate_vector(self, v): ... return self.ambient_vector_space()(v) ``coordinate_vector`` 函数将其输入强制转化环绕空间, 其效果是以 `V` 的形式计算 `v` 的系数向量。 空间 `V` 已经是环绕空间,因为它就是 `\QQ^3`。 子空间也有 ``coordinate_vector`` 函数,它是不同的。我们创建一个子空间并看到: .. skip :: sage: V = QQ^3; W = V.span_of_basis([V.0, V.1]) sage: W.coordinate_vector?? ... def coordinate_vector(self, v): """ ... """ # First find the coordinates of v wrt echelon basis. w = self.echelon_coordinate_vector(v) # Next use transformation matrix from echelon basis to # user basis. T = self.echelon_to_user_matrix() return T.linear_combination_of_rows(w) (如果你认为实现效率低下,请注册以帮助优化线性代数。) 你也可以输入 ``help(command_name)`` 或 ``help(class)`` 来获取给定类的帮助文档(类似 manpage )。 .. skip :: sage: help(VectorSpace) Help on function VectorSpace in module sage.modules.free_module: VectorSpace(K, dimension_or_basis_keys=None, sparse=False, inner_product_matrix=None, *, with_basis='standard', dimension=None, basis_keys=None, **args) EXAMPLES: The base can be complicated, as long as it is a field. :: sage: V = VectorSpace(FractionField(PolynomialRing(ZZ,'x')),3) sage: V Vector space of dimension 3 over Fraction Field of Univariate Polynomial Ring in x over Integer Ring sage: V.basis() [ (1, 0, 0), (0, 1, 0), --More-- 当你输入 ``q`` 退出帮助系统时,你的会话内容将保持不变。 帮助列表不会使你的会话变得杂乱,而 ``function_name?`` 的输出有时会造成这种情况。 输入 ``help(module_name)`` 特别有用。例如,向量空间在 ``sage.modules.free_module`` 中定义, 输入 ``help(sage.modules.free_module)`` 即可获得有关整个模块的文档。 使用帮助查看文档时,可以通过输入 ``/`` 进行搜索,也可以通过输入 ``?`` 反向搜索。 保存和加载单个对象 ================== 假设你计算出一个矩阵或更复杂的模符号空间,并希望将其保存以供日后使用。你要怎么办呢? 计算机代数系统采用多种方法来保存单个对象。 #. **保存游戏:** 仅支持保存和加载完整会话(如 GAP、Magma)。 #. **统一输入输出:** 使每个对象都以可读的方式打印(GP/PARI)。 #. **Eval:** 轻松在解释器中计算任意代码(如 Singular、PARI)。 由于 Sage 使用 Python,因此采用不同的方法,即每个对象都可以序列化, 转化为一个可以从中恢复该对象的字符串。这与 PARI 的统一输入输出方法精神相似, 只不过对象打印到屏幕的方式不会过于复杂。此外,保存和加载在大多数情况下是完全自动的, 不需要额外编程;这是 Python 的设计特性。 几乎所有 Sage 对象 x 都可以以压缩形式保存到磁盘, 使用 ``save(x, filename)`` (或在许多情况下 ``x.save(filename)``)。 要加载对象,使用 ``load(filename)``。 .. skip :: sage: A = MatrixSpace(QQ,3)(range(9))^2 sage: A [ 15 18 21] [ 42 54 66] [ 69 90 111] sage: save(A, 'A') 现在你应该退出 Sage 并重新启动。然后便可以恢复 ``A``: .. skip :: sage: A = load('A') sage: A [ 15 18 21] [ 42 54 66] [ 69 90 111] 可以使用同样的方法处理更复杂的对象,如椭圆曲线。缓存对象的所有数据都与对象一同保存。例如: .. skip :: sage: E = EllipticCurve('11a') sage: v = E.anlist(100000) # takes a while sage: save(E, 'E') sage: quit ``E`` 的存储版占 153K 字节,因为它储存了前 100000 个 `a_n`. .. skip :: ~/tmp$ ls -l E.sobj -rw-r--r-- 1 was was 153500 2006-01-28 19:23 E.sobj ~/tmp$ sage [...] sage: E = load('E') sage: v = E.anlist(100000) # instant! (在 Python 中,保存和加载使用 ``cPickle`` 模块实现。 具体来说,Sage 对象 ``x`` 可以通过 ``cPickle.dumps(x, 2)`` 保存。注意 ``2``!) Sage 无法保存和加载某些其它计算机代数系统(例如 GAP、Singular、Maxima)创建的单个对象。 它们重新加载时状态显示为“无效 (invalid)”。在 GAP 中,虽然许多对象的打印方式可以重新构建, 但很多对象却不行,因此特意不允许从其打印表示进行重建。 .. skip :: sage: a = libgap(2) sage: a.save('a') sage: load('a') Traceback (most recent call last): ... ValueError: The session in which this object was defined is no longer running. GP/PARI 对象可以保存和加载,因为它们的打印表示足以重构它们。 .. skip :: sage: a = gp(2) sage: a.save('a') sage: load('a') 2 保存的对象稍后可以在不同架构或操作系统的计算机上重新加载, 例如,你可以在 32 位 OS X 上保存一个大矩阵,然后在 64 位 Linux 上重新加载它, 计算阶梯形式,然后再保存回去。此外,在许多情况下,即使在不同版本的 Sage 中也能加载对象, 只要该对象的代码没有太大差异。对象的所有属性,以及定义对象的类(但不包括源代码)都会被保存。 如果该类在新版本的 Sage 中不再存在,那么该对象就无法在新版本中重新加载。 但你可以在老版本中加载它,获取其对象字典(使用 ``x.__dict__``),保存该字典,并将其加载到新版本中。 保存为文本 ---------- 你还可以将对象的 ASCII 文本表示保存到纯文本文件中, 只需以写入模式打开文件并写入对象的字符串表示即可(你也可以通过这种方式写入许多对象)。 写完对象后,关闭文件。 .. skip :: sage: R.<x,y> = PolynomialRing(QQ,2) sage: f = (x+y)^7 sage: o = open('file.txt','w') sage: o.write(str(f)) sage: o.close() .. _section-save: 保存和加载完整会话 ================== Sage 对于保存和加载完整会话有非常灵活的支持。 ``save_session(sessionname)`` 命令将所有在当前会话中定义的变量保存为给定 ``sessionname`` 的字典。 (在少数情况下,如果某个变量不支持保存,则不会保存到字典。)生成的文件为 ``.sobj`` 文件, 可以像保存的其它对象一样加载。加载会话保存的对象时,会得到一个字典,字典的键为变量名,值为对象。 可以使用 ``load_session(sessionname)`` 命令将 ``sessionname`` 中定义的变量加载到当前会话。 注意,这不会清除当前会话中已经定义的变量;而是合并两个会话。 首先启动 Sage 并定义一些变量。 .. skip :: sage: E = EllipticCurve('11a') sage: M = ModularSymbols(37) sage: a = 389 sage: t = M.T(2003).matrix(); t.charpoly().factor() _4 = (x - 2004) * (x - 12)^2 * (x + 54)^2 接下来保存会话,将上面定义的每个变量保存至文件。然后查看文件,大小约为 3K。 .. skip :: sage: save_session('misc') Saving a Saving M Saving t Saving E sage: quit was@form:~/tmp$ ls -l misc.sobj -rw-r--r-- 1 was was 2979 2006-01-28 19:47 misc.sobj 最后重新启动 Sage,定义一个额外的变量,并加载保存的会话。 .. skip :: sage: b = 19 sage: load_session('misc') Loading a Loading M Loading E Loading t 每个保存的变量再次可用。此外,变量 ``b`` 没有被覆盖。 .. skip :: sage: M Full Modular Symbols space for Gamma_0(37) of weight 2 with sign 0 and dimension 5 over Rational Field sage: E Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: b 19 sage: a 389