網頁

搜尋此網誌

2014年9月20日 星期六

Black Tea 品味紅茶

最近研究了一下紅茶,在此分享有關紅茶的知識。

紅茶茶葉原產於中國,但卻是英國塑造了紅茶文化,紅茶變成茶的主流,甚至是茶的代名詞。英國人稱紅茶為「Black Tea」是因為紅茶茶葉是黑色的緣故,而我們東方稱為紅茶是因為紅茶茶湯色澤呈現紅褐色的緣故。

奶茶:紅茶加牛奶,或是牛奶加紅茶,這是經濟上的考量,有兩種說法。過去茶葉是奢侈品,為了能夠多喝幾杯,於是加入較便宜的牛奶。另一種說法則是有段時間牛奶供不應求,如果添加紅茶在牛奶之中,就能夠減少牛奶的使用量。不論何者真實,奶茶確實是好喝的飲品之一!

茶葉以產地聞名,也通常以產地命名。全世界公認的紅茶生產地有三個國家:印度、錫蘭與中國,其出產的紅茶如下:
  • 印度,產地位於印度東北部
    • 阿薩姆省 (Assam),稱為阿薩姆紅茶
    • 西孟加拉省 (West Bengal) 的大吉嶺 (Darjeeling),稱為大吉嶺紅茶
  • 斯里蘭卡 (Sri Lanka),統稱為錫蘭紅茶 (Ceylon Tea)。
    • 烏沃省 (Uva)
    • 努沃勒埃利耶區 (Nuwara Eliya)
    • 汀普拉村 (Dimbula)
  • 中國
    • 安徽省祁門縣,出產的紅茶稱為「祁紅」。(祁:讀作ㄑ一 ˊ)
除了上述三個國家外,生產紅茶比較著名國家的還有肯亞、爪哇、台灣。


接下來介紹紅茶的等級 (Grade),所謂的等級和品質無關,純粹只是區分茶葉的大小和生長部位。為什麼要分級呢?因為與泡茶的時間有關,越大片的茶葉沖泡的時間越長。紅茶的等級如下,依照茶葉生長位置由上而下(葉片由小至大):
  • 花橙黃白毫 (Flowery Orange Pekoe, 簡稱 FOP)
  • 橙黃白毫 (Orange Pekoe, 簡稱 OP)
  • 白毫 (Pekoe, 簡稱 P)
  • 白毫小種 (Pekoe Souchong, 簡稱 PS)
  • 小種 (Souchong, 簡稱 S)
若依茶葉的完整性,有沒有切碎處理,可以分為下列 3 種:
  • 全葉茶 (Leaf, 沒有簡稱),或稱葉茶。
  • 碎茶 (Broken, 簡稱 B),或稱散茶。沖泡時間較全葉茶短。
  • 粉茶 (Dust, 簡稱 D),或稱末茶。沖泡時間最短,分級過程中剩下的細粉狀茶葉,通常也最廉價。
了解產地與分級,最後介紹紅茶的調和變化,這大概是紅茶比較特別的地方。從產地出來是怎樣就是怎樣的紅茶,稱為原味茶,或稱產地茶。而調和兩種以上的原味茶,則稱為混合茶。若是在原味紅茶製作過程加入其他果香味,則是加味茶。以下是這些變化中較知名的紅茶清單:
  • 原味茶 (Plain Tea)
    • 阿薩姆 (Assam Tea)
    • 大吉嶺 (Darjeeling Tea)
  • 混合茶 (Blended Tea)
    • 英國早餐茶 (English Breakfast Tea),混合印度、錫蘭或肯亞的產地茶調配而成的紅茶。
    • 英國下午茶 (English Afternoon Tea),混合印度及非洲的產地茶調和而成的紅茶。
  • 加味茶 (Flavoured Tea)
    • 伯爵茶 (Earl Grey Tea),在中國的英國外交使節格雷 (Earl Grey) 伯爵將中國茶葉調製的祕方帶回給傑克森 (Jacksons) 公司而聞名,主要是紅茶調和品味紅茶的香氣而醞釀的獨特風味。
    • 仕女伯爵紅茶 (Lady Grey Tea),紅茶加橘皮、檸檬皮和矢車菊葉所調製的。
    • 薄荷紅茶
參考書籍
孟樊,寫意紅茶:在杯中、書中、影中品味紅茶,臺北:時報文化,2007。

###

2014年9月12日 星期五

subprocess 子行程管理

subprocess 是 Python  程式語言中用來新增子行程的模組,這是在 PEP 324 中所提出的建議,主要是統一 Python 新增子行程的方法,用來取代 os.system, os.spawn*, os.popen*, popen2.*, commands.* 等這些模組和函式。基本上,在  Python 中如果要新增子行程,你只要知道 subprocess 模組就行了

subprocess 模組最重要的是 Popen 類別,建立 Popen 物件時將會新增子行程去執行你要的工作,Popen 類別用起來比較精細,可操作的地方較多,相對較麻煩一些。因此 subprocess 模組提供下列三種方便的函式來新增子行程,注意到這三個函式是屬於同步呼叫 (synchronous call) 的方式,一定會等到子行程結束才執行下一行程式碼。
  • subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
    最簡單的子行程新增方式,執行並等待結束,回傳子行程的回傳值 (return code)。
  • subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
    呼叫子行程,並判斷回傳值是否為是否為 0,不然就引發 CalledProcessError 例外。
  • subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)
    呼叫子行程,與 subprocess.check_call 函式行為相似,但回傳 stdout 的字串值。
接下來介紹 Popen 類別,Popen 的建構子如下:
class subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

Popen 物件則有下列方法和屬性:
  • 方法
    • Popen.poll():判斷子行程是否結束,如果結束回傳 returncode 值,否則回傳 None 。
    • Popen.wait():等待子行程結束,回傳 returncode 值。
    • Popen.communicate(input=None):與子行程通訊,回傳 tuple 資料型態為 (stdoutdata, stderrdata),注意要通訊的 stdin, stdout, stderr 引數必須設定為 subprocess.PIPE 。
    • Popen.send_signal(signal):送信號給子行程。
    • Popen.terminate():終止子行程,送出 SIGTERM 信號。
    • Popen.kill():停止子行程,送出 SIGKILL 信號。
  • 屬性
    • stdin:如果建立 Popen 時的 stdin 引數是 subprocess.PIPE,那麼這個屬性會是 file object,否則為 None。
    • stdout:如果建立 Popen 時的 stdout 引數是 subprocess.PIPE,那麼這個屬性會是 file object,否則為 None。
    • stderr:如果建立 Popen 時的 stderr 引數是 subprocess.PIPE,那麼這個屬性會是 file object,否則為 None。
    • pid:子行程的 process ID。
    • returncode:子行程結束的回傳值,如果子行程還在執行沒有結束,returncode 會是 None 。
最後,注意 shell 引數若設定為 True 時,我們必須確定空白字元shell metacharacters 有被引號正確地包起來,不然建立子行程會錯誤或不如預期。預設的 shell=False 使 subprocess 模組會完整傳送所有字元,包含 shell metacharacters。看下列範例會更清楚

import subprocess
subprocess.check_output(['printf','Hello World\n'])
subprocess.check_output(['printf "Hello World\n"'], shell=True)
subprocess.check_output('printf "Hello World\n"', shell=True)

上述 3 行程式碼執行結果是相同的,差別在於 shell=True 時必須用引號處理空白和 metacharacters,最後一行則是因為序列 (sequence) 的引數只有一個,可以簡化成字串作為引數。

文件中建議,如果讓使用者輸入參數作為子行程的引數會有安全行的問題,容易發生 Shell injection 的危險,如果你很確定引數沒有任何疑慮,使用 shell=True 倒是讓程式碼更容易閱讀。

###

熱門文章