本文節錄自《 Learning Python 》一書第十章〈Frameworks and Applications〉
JPython 是最近出現的一個 Python 分支
由 Jim Hugunin 先生完全以 Java 撰寫完成
對於 Python 和 Java 陣營來說
JPython 的出現相當令人興奮
Python 使用者相當高興他們現有的 Python 知識可以應用到 Java 的開發環境中
Java 的使用者也很高興他們能夠使用 Python 當作描述語言(scripting language)來操作 Java 系統
測試鏈接庫
並在直譯環境中學習 Java 鏈接庫
你可以在 取得 JPython
其授權方式類似於 CPython(為了有別於 Java 版的 JPython
原先版本的 Python 改叫 CPython )
JPython 安裝好之後
包含了
l jpython
JPython 的直譯環境
l jpythonc
用來將 JPython 程序編譯成 Java 的 bytecode
產生出來的程序就和一般的 Java 類別檔沒有兩樣
可以用來產生 applet
servlet
bean 等
l 一套程序模塊
提供標准的 Python 鏈接庫給 JPython 的使用者
l 一些范例程序
用來展示 JPython 的多重風貌
JPython 的使用方式和 Python 很類似
請看下面的例子
~/book> jpython
JPython
on java
beta
Copyright
Corporation for National Research Initiatives
>>>
+
事實上
JPython 和 CPython 的運作方式幾乎一樣
想知道兩者有何真正的差異
最新的資料可以從 取得
其中最大的差異在
l JPython 目前比 CPython 慢
有多慢?這會因 Java 虛擬機器和 JPython 測試程序的不同而有異
不過
JPython 的作者已經承諾未來會做最佳化
使得 JPython 的速度會和 CPython一樣快
甚至更快
l JPython 欠缺一些內建模塊或鏈接庫模塊
比方說
不能使用 os
system()
因為這會造成 Java 和底層 OS 互動的困擾
有一些 CPython 所具備的大型延伸模塊(比方說
Tkinter)也在 JPython 中付之阙如
因為 Java 環境原本就不具備這些工具(比方說 Tk/Tcl )
透過 JPython
Python 程序員可以使用 Java 鏈接庫 JPython 可以讓 Python 程序員天衣無縫地使用 Java 鏈接庫
而這是 CPython 做不到的
請看下面的程序 jpythondemo
py 和其執行結果
from pawt import swing
import java
def exit(e): java
lang
System
exit(
)
frame = swing
JFrame(
Swing Example
visible=
)
button = swing
JButton(This is a Swinging button!
actionPerformed=exit)
ntentPane
add(button)
frame
pack()
透過這個簡單的程序
你可以看出
寫一個用 Java Swing 來當 GUI 的 Python 程序相當簡單
第一行先引入(import)Swing 的package(pawt 表示目前 Swing 模塊的所在位置
可以是在 java
awt
swing
或 com
sun
java
swing
或 javax
swing)
第二行引入 java package
因為待會程序中會用到 java
lang
System
exit()
第四行建立一個 JFrame 對象
並設定此 JFrame 組件的 visible 屬性為「真」
第五行建立一個 JButton 對象
設定其標示文字
並指定按鍵被按下時必須執行的函式為 exit()
最後兩行把此 JButton 對象放到 JFrame 對象中
再將 JFrame 的大小調到剛好
有經驗的 Java 程序員可能會對 jpythondemo
py 程序中的某些部分感到有些吃驚
因為它和對等的 Java 程序有些差異
為了要讓 JPython 中使用 Java 鏈接庫和 CPython 中一樣簡單
JPython 在背後做了許多事
比方說
當 JPython 引入(import)一個 Java package
就會主動地往下追蹤適當的 package
然後透過 Java Reflection API 找出 package 的內容
類別和 method 的 signature
JPython 也會實時進行 Python 和 Java 之間的型態轉換
比方說
在 jpythondemo
py 程序中
按鍵的文字「This is a Swinging example!」是 Python 的字符串
在呼叫 JButton 的 constructor 之前
JPython 會先找出正確的 constructor(透過參數來判斷)
然後自動將 Python 的字符串轉成 Java 的字符串
JPython 內部甚至用了更精巧的方式來允許你在 JButton 的 constructor 中方便地使用「actionPerformed=exit」當作參數
這種作法是 Java 所沒有的
因為 Java 不允許 function(或 method)當作參數
在 JPython 中
你不用像 Java 需要為了提供 actionPerformed method 而建立一個 ActionListener 類別(當然你也可以在 JPython 中使用 Java 的方式
如果你不嫌啰唆的話)
JPython as a Java Scripting Language
JPython 越來越受歡迎
因為它允許程序員去探究不斷出現
形形色色的 Java 鏈接庫
大家也發現 JPython 可以幫助在 Java 中嵌入 Python 當作描述語言(scripting language)
來讓最終使用者量身打造
測試
或進行其它程序設計工作
關於這方面更進一步的資料
在 JPython 軟件的demo/embed 次目錄中有更詳細的說明
一個真正的 JPython/Swing 范例
grapher
py
grapher
py 程序(外觀如下圖)允許使用者用圖形的方式來觀察數學函數的圖形
本程序也用到 Swing GUI 套件
畫面上有兩個文字字段需要填入 Python 程序
在上面的字段中填入任意的Python 程序
在此引入(import)所需要的模塊
並定義相關函數
第二個字段(標式示「Expression:」)中填入 Python 的計算式(比方說 sin(x))
而非填入 Python 敘述
繪圖時每個水瓶坐標 x 值都會代入此計算式
使用者可以自行控制繪出的圖形是線狀圖或實心圖
也可以決定繪圖點數
顏色
而且
還可以把設定存到磁盤中
下次再叫出來(透過 pickle 模塊)
下面就是 grapher
py 的程序代碼
from pawt import swing
awt
colors
GridBag
RIGHT = swing
JLabel
RIGHT
APPROVE_OPTION = swing
JFileChooser
APPROVE_OPTION
import java
io
import pickle
os
default_setup =
from math import *def squarewave(x
order):
total =
for i in range(
order*
+
):
total = total + sin(x*i/
)/(float(i))
return total
default_expression =
squarewave(x
order=
)
class Chart(awt
Canvas):
color = colors
darkturquoise
style =
Filled
def getPreferredSize(self):
return awt
Dimension(
)
def paint(self
graphics):
clip = self
bounds
lor = colors
white
graphics
fillRect(
clip
width
clip
height)
width = int(clip
width *
)
height = int(clip
height *
)
x_offset = int(clip
width *
)
y_offset = clip
height
int(clip
height *
)
N = len(self
data); xs = [
]*N; ys = [
]*N
xmin
xmax =
N
ymax = max(self
data)
ymin = min(self
data)
zero_y = y_offset
int(
ymin/(ymax
ymin)*height)
zero_x = x_offset + int(
xmin/(xmax
xmin)*width)
for i in range(N):
xs[i] = int(float(i)*width/N) + x_offset
ys[i] = y_offset
int((self
data[i]
ymin)/(ymax
ymin)*height)
lor = lor
if self
style ==
Line
:
graphics
drawPolyline(xs
ys
len(xs))
else:
xs
insert(
xs[
]); ys
insert(
zero_y)
xs
append(xs[
]); ys
append(zero_y)
graphics
fillPolygon(xs
ys
len(xs))
# draw axes
lor = colors
black
graphics
drawLine(x_offset
zero_y
x_offset+width
zero_y)
graphics
drawLine(zero_x
y_offset
zero_x
y_offset
height)
# draw labels leading = graphics
font
size
graphics
drawString(
%
f
% xmin
x_offset
zero_y+leading)
graphics
drawString(
%
f
% xmax
x_offset+width
zero_y+leading)
graphics
drawString(
%
f
% ymin
zero_x
y_offset)
graphics
drawString(
%
f
% ymax
zero_x
y_offset
height+leading)
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19740.html