我可以在组织模式下将公共代码块包含在两个不同的代码块中吗?


12

我有一个org-mode包含数据表和两个Python代码块的文件,用于从中提取不同的摘要。

我想在这两个代码块之间共享一些公共常量和函数。理想情况下,我可以通过将通用代码分解为一个单独的代码块来进行此操作,只要对其他两个块中的任何一个进行评估,该代码块都会自动包含并对其进行评估。用伪造的语法,它看起来类似于以下内容:

#+NAME: init_block
#+BEGIN_SRC python
  ... common constants and functions here ...
#+END_SRC

#+NAME: summary_1
#+BEGIN_SRC python :prepend init_block
  ... data-processing code depending on init code goes here ...
#+END_SRC

#+NAME: summary_2
#+BEGIN_SRC python :prepend init_block
  ... more processing which also depends on init code ...
#+END_SRC

我想我可以使用该:session选项,但是由于两个原因,我不愿意使用该选项。首先,它建立了一个有状态的系统,而不是每次我C-c C-c在代码块上使用时都会从头开始运行的系统。其次,与此相关的是,我现在必须记住每次打开文件时都要手动评估通用的初始化代码:我不能只是更新数据表,转到摘要块之一并单击C-c C-c以对其进行更新。

有什么好方法吗?

Answers:


15

使用org-babel的noweb参考语法进行识字编程,您可以最轻松地做到这一点。这是一个例子:

* Initialization block containing function definition
#+NAME: init_block
#+BEGIN_SRC python
  constant=19
  def some_function(x):
    return constant * x
#+END_SRC

* Call the function on an integer
#+BEGIN_SRC python :noweb yes 
  <<init_block>>
  return some_function(13)
#+END_SRC

#+RESULTS:
: 247

* Call the function on a string
:PROPERTIES:
:noweb:    yes
:END:

#+BEGIN_SRC python
  <<init_block>>
  return some_function('abc')
#+END_SRC

#+RESULTS:
: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc

谢谢。这看起来很棒,比我的骇人解决方案好得多。我将在接下来的几天中尝试一下,看看是否有任何问题。
乔恩·O。

@JonO。如果这个答案对您有用,那么您是否会接受它是正确的-谢谢
2014年

4

经过多思考,我找到了解决该问题的部分方法。它确实使用:session,但是我至少可以确保在评估其他模块之一之前,总是始终自动运行通用初始化代码。“技巧”是使用引用头块的伪头变量,从而导致每次对其进行评估:

#+NAME: init_block
#+BEGIN_SRC python :session t
  constant=19
  def some_function(x):
    return constant * x
#+END_SRC

#+BEGIN_SRC python :session t :var dummy=init_block
some_function(13)
#+END_SRC

#+RESULTS:
: 247

现在,我可以更改定义,init_block并在每次:var dummy=init_block评估使用它的引用块时对其进行自动重新评估。只要其中的定义init_block是幂等且无状态的,这将很好地工作。

(请注意,将Python块更改为:session模式时,您必须删除所有return语句,这些语句在功能模式下需要从该块返回值)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.