直接執行Python腳本:Python Caller / Running a Python Script Directly in Windows: Python Caller
繼前一篇的RScript Caller之後,這次要來介紹的是直接執行Python的Python Caller。這隻程式的主要目的是提供讓Python腳本檔案(副檔名為.py)直接關聯到Python-Caller.exe,這樣就能在檔案總管中點兩下直接執行,然後在執行完畢後暫停,讓開發者可以看看執行結果。以下就是Python Caller的下載、設定與使用介紹。因為做法跟RScript Caller蠻像的,所以兩篇內容會看起來很像就是了。
下載 / Download
- GitHub專案首頁:https://github.com/pulipulichen/Python-Caller
- 下載網址:https://github.com/pulipulichen/Python-Caller.git
下載後直接解壓縮即可。
這邊我們會用到以下兩個檔案:
- Python-Caller.exe 主程式,要讓Python腳本 (副檔名為.py) 關聯到這個主程式。
- config.ini 設定檔,設定Python環境的路徑。
設定 / Configuration
要使用Python-Caller.exe的話,要先設定config.ini中Python環境的路徑,然後再將Python腳本(副檔名為.py)關聯到Python-Caller.exe主程式。以下我們就來看看怎麼做吧。
設定檔 / config.ini
請用文字編輯器開啟config.ini。我推薦使用Notepad++來編輯。
設定檔中我們要編輯的是path參數。裡面需要設定Python安裝的位置。通常Python預設安裝在「=C:\Program Files\Python27\python.exe」,而紅字的「Python27」是指你的Python版本,表示是2.7版。至於要用Python 2或Python 3是端看你的Python腳本需求,這裡並沒有特別建議要用那個版本才好。(關於Python 2跟Python 3的差異,可以看Python2和Python3備受爭議,咱們花五分鐘瞭解Python3語言特性!)
請確認你的Python是否真的安裝在這個位置。如果你沒有安裝Python,請先到Python官方網站下載安裝:
關聯程式 / Associate .py file with Python Caller
讓我們用同資料夾底下的example.py來設定Python腳本檔案的關聯程式。請在該檔案上按右鍵,進入「開啟檔案」中的「選擇預設程式」。
按右下角的「瀏覽」。
選擇剛剛下載的資料夾中的「Python-Caller.exe」,開啟。
確認Python-Caller.exe已經正確選擇了,然後按下「確定」。
這時候就可以看到example.py的執行結果了,是的,它就是一個「Hello, World!」。
使用 / Usage
如果正確設置了Python-Caller.exe,那以後只要對副檔名為「.py」的Python腳本檔案雙擊開啟,就會自動呼叫Python-Caller.exe執行Python腳本。
讓我們以循序樣式探勘:以Python的PrefixSpan實作中的Python腳本檔案prefixspan.py為例子,來看看使用Python Caller執行起來會是什麼樣子吧。該腳本還需要搭配資料檔案input.csv才能使用,請一併下載。如果你不會從GitHub下載檔案,請看如何從GitHub下載檔案這篇。
以上是我用ScreenToGIF錄下來的執行過程,可以看到執行過程中變成用GUI詢問要分析的檔案跟門檻,然後就在輸入檔案旁邊得到了分析結果。這樣子執行Python腳本就很方便了呢。
Python腳本開發建議 / Hints for developing Python scripts
其實Python Caller在昨天我寫完RScript Caller的介紹之後就完成了,但後來的時間我都在研究怎麼寫一個可以獨立執行的Python腳本。最後我把心得寫在example-gui.py這個檔案中,重點如下:
在腳本中安裝套件 / Install packages programmatically
以往我們都是在指令列以pip安裝Python的套件,但如果要讓使用者直接執行Python腳本、省下還要額外開啟命令提示字元視窗來用pip的困擾,那我們應該在Python腳本中直接呼叫pip安裝套件。
我找到比較合適的做法是來自rominf的建議,以下是在Python腳本中安裝docopt套件的做法:
# install package programmatically
import pip
def install_and_import(package):
import importlib
try:
importlib.import_module(package)
except ImportError:
import pip
pip.main(['install', package])
finally:
globals()[package] = importlib.import_module(package)
install_and_import('docopt')
from docopt import docopt
以後要安裝其他套件時,只要呼叫install_and_import()函數就可以了。
附帶一提,在R裡面安裝並匯入套件的做法還蠻常見的,做法如下:
if(!require(dplyr)){install.packages("dplyr")}
而在Node.js中似乎也有類似Python呼叫pip的做法,可以在Node.js中呼叫npm,寫法參考自hexacyanide:
var npm = require('npm');
npm.load(function(err) {
// handle errors
// install module ffi
npm.commands.install(['ffi'], function(er, data) {
// log errors or data
});
npm.on('log', function(message) {
// log installation progress
console.log(message);
});
});
使用GUI對話視窗 / GUI dialogs
Python提供了Tkinter (在Python 3叫做tkinter)的圖形化介面對話視窗功能,讓使用者可以自行指定要輸入的檔案或資料夾,以及設定的參數,非常方便。
我們在使用前必須要先載入函式庫。但是Python 2跟Python 3中此套件的名稱並不相同,我參考d-coder的做法,用以下方法來達到Python 2跟Python 3兼容的載入方式:
# Python 2-3 compatible
try:
from Tkinter import Tk
from tkFileDialog import askopenfilename
from tkSimpleDialog import askinteger
except:
from tkinter import tk
from filedialog import askopenfilename
from simpledialog import askinteger
然後我們就可以呼叫Tkinter的功能。以下是簡單的檔案選擇跟參數輸入的示範:
# tkinter GUI
Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing
filename = askopenfilename(initialdir=os.path.dirname(os.path.realpath(sys.argv[0])),
title="Please select a Python script:",
filetypes=[('Python script', '.py')]) # show an "Open" dialog box and return the path to the selected file
print(filename)
intresult = askinteger("Ask a integer", "Which number you like? [1-5]",
minvalue=1, maxvalue=5, initialvalue=3)
print(intresult)
不過這段範例不確定能否在Python 3裡面順利運作,有機會我再來測試吧。
askopenfilename()會跳出檔案選擇視窗來供使用者選擇檔案。在範例中,我還設定了一開始資料夾的路徑、對話視窗的標題跟可以選擇的檔案類型。
askinteger()則是請使用者輸入數字。在範例中,我也設定了對話視窗標題、內文、最小值、最大值、以及預設值。
有了這些功能,就能夠開發擁有完整GUI功能的單一Python腳本了吧。
結語 / In closing
由於這篇跟RScript Caller的內容大部分都蠻像的,所以我在後面多加了一些額外的介紹,希望未來可以用這樣的方式來開發好用的Python腳本。
Python Caller的功能就跟Python.exe本身還蠻像的,但是加入了「pause」暫停之後,就可以保留執行結果視窗以便查看。這個小功能對開發者來說格外的重要。而且還可以將多次執行的結果以獨立的命令提示資源視窗顯示,這也是很方便的地方。
好,R跟Python都寫完了,那下次就是回頭來改Node.js Caller吧。
這篇用Python Caller執行Python腳本的介紹就到這邊囉。你平常也都是用命令提示字元在指令端中執行Python腳本嗎?這樣子的做法跟這篇用Python Caller來呼叫,你比較喜歡那個呢?如果你有什麼建議的話,歡迎在下面留言提出指教。如果你覺得Python Caller還不錯用的話,請幫我在AddThis分享工具按讚、將這篇分享到Facebook等社群媒體吧!感謝你的耐心閱讀,讓我們下一篇見。