寫Python的新方式

Org mode is for keeping notes, maintaining TODO lists, planning projects, and authoring documents with a fast and effective plain-text system.

Org-mode 類似于 Markdown , 但是遠勝于 Markdown 趁冈。 曾有小伙伴說過, Org-modeMarkdown 的封神模式, 個人覺得這話一點不夸張, 相比較而言, Markdown 只是一套簡潔的文檔格式吭净, 而 Org-mode 除了涵蓋作為文檔格式的簡潔之外, 還可用于記筆記,維護 TODO 列表坯辩, 工程管理,以及可用于元編程。 對于元編程的支持請閱讀我之前的譯文崩侠, Babel: org-mode的元編程漆魔。

所謂的元編程,即是 Org-mode 搭建了一個多語言可以交互執(zhí)行的環(huán)境却音, 在這個環(huán)境中改抡,可選用各語言的特性,來分解執(zhí)行一個大型任務(wù)系瓢。

Org-mode 對于比較流行的語言都有很好的支持阿纤, 而且對于新語言,也可以很容易添加支持夷陋,本人就給兩種語言添加過支持欠拾。 本文章主要講述 Org-mode 對于 Python 源代碼塊的支持, Python 相當?shù)牧餍? 所以在 Org-mode 中被很完美的支持。 Org-mode 中的 Python 源代碼塊可用于定義函數(shù)骗绕、過濾器和數(shù)據(jù)分析藐窄、創(chuàng)建圖表以及生成可重現(xiàn)的研究論文。

配置

這里假設(shè) Python 的開發(fā)環(huán)境已配置完畢酬土,若是還沒配置枷邪,請自行g(shù)oogle。

Org-mode 已內(nèi)置在新的 Emacs 中,但是默認情況下东揣, 只有 emacs-lisp 可被執(zhí)行践惑。 要啟用或禁用其他語言, 可通過 Emacs 自定義交互界面來配置 org-babel-load-languages 變量, 或者將代碼添加到 init 文件中, 啟用python的代碼如下所示:

(org-babel-do-load-languages
 'org-babel-load-languages
 '((python . t)))

Org-mode對于Python源碼塊的支持

頭參數(shù)

語言特定的頭參數(shù)

  • :results {output, value}: 默認 value 模式, 即 functional mode, 像函數(shù)一樣執(zhí)行,然后返回計算結(jié)果嘶卧。
  • :preamble: 前導(dǎo)代碼尔觉,插入到最前面(不常用)。 默認為空芥吟。
  • :return: 要返回的值(僅用于result-type為 value 時侦铜,不在 session 模式下;不常用)。 默認值為空钟鸵,在 Non-session 模式下钉稍,使用 return() 返回值。
  • :python: 執(zhí)行Python代碼的程序名稱棺耍。

公共頭參數(shù)

  • :seesion [name]: 默認非 session 模式贡未。
  • :var data=data-table: Org-modetable 可被當做列表傳遞給Python代碼塊。
  • :exports {code, results, both, none}: 完全支持 babel 的導(dǎo)出選項蒙袍。

Sessions

python完全支持 session 模式俊卤,包括命名 session 。 在 session 模式下害幅,代碼塊都運行在同一個長時間運行的 python 的交互式解釋器 session 中消恍,就像你在交互式 python 鍵入的一樣。 可以擁有多個 session 以现,而且它們是完全相互獨立狠怨。

session 可用于定義函數(shù),設(shè)置變量和在源塊之間共享代碼邑遏。

python中的 session 模式與 non-session 模式略有不同取董,因為在 session 模式下, 你正在與單個“交互式” python session 交互无宿。 在 python 的交互模式中,空行是特殊的:它們表示縮進代碼塊的結(jié)束, 所以會寫出一些稍微不同的 python 代碼枢里。

另外孽鸡,在 non-session 模式下,python代碼塊將被包裝在一個函數(shù)中栏豺, 所以要返回一個值( :result value mode )彬碱,你必須使用一個return語句。 在 session 模式下奥洼, python 代碼由解釋器直接評估巷疼,而不是在一個函數(shù)的上下文中, 最后一個語句的值將被自動返回灵奖,因此不能使用 return 語句嚼沿。

Session mode

# blank lines not OK in indented blocks, and don't use return()
# Source block is passed directly to interactive python;
# value is value of _ at end.
#+begin_src python :session
def foo(x):
  if x>0:
    return x+1
  else:
    return x-1

foo(1)
#+end_src

#+RESULTS:
: 2

Non-session mode

# blank lines OK in indented blocks, and use return()
# Entire source block will get indented and used as the body of main()
#+begin_src python
def foo(x):
  if x>0:
    return x+1

  else:
    return x-1

return foo(5)
#+end_src

#+RESULTS:
: 6

最后估盘,如果你使用 matplotlib 的圖形功能,同時使用 seesion 模式骡尽, 必須顯式設(shè)置后端, 例如 PDF , PNG 或其他文件導(dǎo)出后端遣妥。 見下面示例:

#+begin_src python :session :results file
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
fig=plt.figure(figsize=(3,2))
plt.plot([1,3,2])
fig.tight_layout()
plt.savefig('images/myfig.pdf')
'images/myfig.pdf' # return this to org-mode
#+end_src

#+RESULTS:
[[file:images/myfig.pdf]]

返回類型

  • value:=value= 結(jié)果是代碼塊中求值的最后一個表達式的值。 session 模式下使用的python解釋器特殊變量“_” 來引用最后一個表達式的值攀细。
  • output:=output= 結(jié)果來自 python 代碼打印到 stdout 上任意信息箫踩。

示例

  • Hello World!

    #+begin_src python :results output
      print "Hello, world!"
    #+end_src
    
    #+RESULTS:
    : Hello, world!
    
  • 參數(shù)

    #+NAME: square
    #+BEGIN_SRC python :var num=5
      def square(x):
          return x*x
    
      return square(num)
    #+END_SRC
    
    #+RESULTS: square
    : 25
    
    #+CALL: square(num=10)
    
    #+RESULTS:
    : 100
    
  • 文學(xué)編程

    #+NAME: square
    #+BEGIN_SRC python
      def square(x):
          return x*x
    #+END_SRC
    
    #+NAME: calc-square
    #+BEGIN_SRC python :var num=5 :noweb strip-export :results output
      <<square>>
      print(square(num))
    #+END_SRC
    
    #+RESULTS: calc-square
    : 25
    
    #+CALL: calc-square(num=7)
    
    #+RESULTS:
    : 49
  • 內(nèi)聯(lián)調(diào)用(Inline calling):

    2 加 2 等于 src_python{return(2+2)}
    

    當導(dǎo)出 HTML 或者 LaTeX/PDF 時,如下所示:

    2 加 2 等于 4
    
  • 使用Org-mode的table作為參數(shù)

    #+tblname: data_table
    | a | 1 |
    | b | 2 |
    | c | 3 |
    #+begin_src python :var val=1 :var data=data_table
    # Return row specified by val.
    # In non-session mode, use return to return results.
    return(data[val])
    #+end_src
    
    #+RESULTS:
    | b | 2 |
    
  • 繪圖

    #+begin_src python :results file
      import matplotlib, numpy
      matplotlib.use('Agg')
      import matplotlib.pyplot as plt
      fig=plt.figure(figsize=(4,2))
      x=numpy.linspace(-15,15)
      plt.plot(numpy.sin(x)/x)
      fig.tight_layout()
      plt.savefig('../images/python-matplot-fig.png')
      return '../images/python-matplot-fig.png'
    #+end_src
    
    #+RESULTS:
    [[file:../images/python-matplot-fig.png]]
    
python-matplot-fig.png
  • 詞云
    #+BEGIN_SRC python :preamble "# -*- coding: utf-8 -*-" :results value file
      import jieba.analyse
      from wordcloud import WordCloud, ImageColorGenerator
      import numpy as np
      from PIL import Image
      import random
    
      font_path = '../resource/tyzkaishu.ttf'
      width = 640
      height = 480
    
      text = open('../resource/xiyouji.txt').read()
      words = jieba.analyse.extract_tags(text, topK=200, withWeight=True)
    
      word_freqs = {}
      for word in words:
          word_freqs[word[0]] = word[1]
    
      mask = np.array(Image.open('../resource/stormtrooper_mask.png'))
      wordcloud = WordCloud(
          font_path=font_path, width=width, height=height,
          mask=mask).generate_from_frequencies(word_freqs)
      wordcloud.to_file('../images/xiyouji-mask.png')
      return '../images/xiyouji-mask.png'
    #+END_SRC
    
    #+RESULTS:
    [[file:../images/xiyouji-mask.png]]
xiyouji-mask.png

前方預(yù)警

當把 utf-8 的字符串傳給 Python , 需要格外小心谭贪。

傳遞utf-8字符串到Python

#+NAME: unicode_str
#+BEGIN_EXAMPLE
  “this string is not ascii!”
#+END_EXAMPLE

#+NAME: error-in-passing-var
#+BEGIN_SRC python :var data=unicode_str
  return data
#+END_SRC

#+RESULTS: error-in-passing-var

上面代碼不會生成任何輸出, 并在 *Org-Babel Error Output* 的緩沖區(qū)中打印以下消息:

File “<stdin>”, line 3 SyntaxError: Non-ASCII character ’\xe2’ in file <stdin> on line 3, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

傳遞utf-8字符串到Python的變通方法

一個變通方法是使用 :preamble ,如下所示:

#+NAME: ok-in-passing-var
#+BEGIN_SRC python :preamble "# -*- coding: utf-8 -*-" :var data=unicode_str
  return data
#+END_SRC

#+RESULTS: ok-in-passing-var
: “this string is not ascii!”

參考文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末境钟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子俭识,更是在濱河造成了極大的恐慌慨削,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鱼的,死亡現(xiàn)場離奇詭異理盆,居然都是意外死亡,警方通過查閱死者的電腦和手機凑阶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門猿规,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人宙橱,你說我怎么就攤上這事姨俩。” “怎么了师郑?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵环葵,是天一觀的道長。 經(jīng)常有香客問我宝冕,道長张遭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任地梨,我火速辦了婚禮菊卷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宝剖。我一直安慰自己洁闰,他們只是感情好,可當我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布万细。 她就那樣靜靜地躺著扑眉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上腰素,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天聘裁,我揣著相機與錄音,去河邊找鬼耸弄。 笑死咧虎,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的计呈。 我是一名探鬼主播砰诵,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼捌显!你這毒婦竟也來了茁彭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤扶歪,失蹤者是張志新(化名)和其女友劉穎理肺,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體善镰,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡妹萨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了炫欺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片乎完。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖品洛,靈堂內(nèi)的尸體忽然破棺而出树姨,到底是詐尸還是另有隱情,我是刑警寧澤桥状,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布帽揪,位于F島的核電站,受9級特大地震影響辅斟,放射性物質(zhì)發(fā)生泄漏转晰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一士飒、第九天 我趴在偏房一處隱蔽的房頂上張望查邢。 院中可真熱鬧,春花似錦变汪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春番官,著一層夾襖步出監(jiān)牢的瞬間庐完,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工徘熔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留门躯,地道東北人。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓酷师,卻偏偏與公主長得像讶凉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子山孔,可洞房花燭夜當晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容