我觉得两种的使用场合不同,并不能简单的认为哪一种更优越。
对于 :session 模式,它的作用主要是始终可以访问同一个 :session,这样的话你随时可以 访问指定 :session 中的变量。比如下列代码:
#+begin_src ipython :session mysession
import numpy as np
var = np.pi * 2
#+end_src
这样,下次如果需要访问这个变量 var
的时候,不需要重新启动一个进程,而只需要指定 var
所在的 session 就可以了:
#+begin_src ipython :session mysession
print var
#+end_src
这实际上提供了类似于 ipython notebook 的功能,这对于交互式计算非常有帮助。特别是当你前面的运算非常耗时的时候,你不会希望每次都从头开始。
另一方面, 当使用 :noweb 而不是 :session 的时候,代码每次都是从头运行,这样的好处是 每次重新打开 buffer 后,不需要将前面的 src block 都运行一遍,但是缺点是:和单个 non session block 一样,每次运行完后即退出进程,下次会重新开始运行。
另外, :noweb 的用途不仅在 evaluate,还在于 tangle 以及 export 上。
综上,这两种有不同的使用情形,应该根据你的需要灵活选择。
欢迎大家加入讨论!
PS:我觉得论坛的 markup 貌似有点问题,因为上面的代码块结构相似,但是 highlight 的效果截然不同。
1 个赞
我倾向于 :noweb
,大概是因为我的使用场景,并不涉及大量消耗资源的运算,相反,我更在意的是
- block 的组合使用
- 被引用的 block 修改之后立即生效,避免因忘记 C-c C-c 而产生的乌龙
- 结果的一致性,每次都是从头开始,不会因为中间某个 block 执行了多次,导致结果超出预期
也许在代码补全方面,可以 hack 一下语言 mode,例如 python,把 <<bolck_name>>
当作 import
对待,会比较容易实现。
你使用了 Github Flavored Markdown Fenced Code Blocks 并且没有设置语言,于是论坛就会猜测你所用的是哪种语言,于是自然会有猜错的时候。你可以自己手动设置语言 python
,或者用原生的 Code Block(行首 4 个空格)来避免高亮。
1 个赞
我有时会偷懒用 org-mode 来写测试(就是很多人都不愿意写的那种测试)。
把条件/需要复用的代码写在 block1, block2, …blockn。
然后写用例:
- test1 引用 block1/3/5
- test2 引用 block2/4/6
- test3 引用 block1/2/3
- …
这样每个 test 块的输出都是可预期的,不必担心那些前置的 block 已经运行过多少次/缓存了什么。
另,:session
和 :noweb
并不相互排斥,完全可以共存:
#+BEGIN_SRC python :results silent :session
import time
import datetime
def timestamp(str):
ts = datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S')
return '[%s] %s' % (str, ts)
session_ts = timestamp('session')
#+END_SRC
# ------------------------------------------------------------------
#+NAME: noweb_ts
#+BEGIN_SRC python :results none :noweb yes
noweb_ts = timestamp('noweb')
#+END_SRC
# ------------------------------------------------------------------
#+BEGIN_SRC python :results output :session :noweb yes
<<noweb_ts>>
print(session_ts)
print(noweb_ts)
#+END_SRC
#+RESULTS:
: [session] 2017-04-12 11:47:18
: [noweb] 2017-04-12 11:47:50
上边混用了两种块,session 的时间戳是固定的,noweb 每次都更新。
但是如果没有性能上的考量,我认为 :noweb
在使用上更轻松一些,不用每次修改后重新执行,可以更细致地控制块与块之间的引用和依赖。
1 个赞
完全同意, 但是我一般还是习惯 :session, :noweb 只是在 tangle 的时候用。org 的 babel 使用场景太灵活了,100 个人就有 100 种不同的用法,再加上各种 hack,简直了。。。所以用上手 babel 以后果断放弃 ipython notebook 了。