Jython - 快速指南


Jython - 概述

Jython 是 Python 编程语言的 JVM 实现。它被设计为在Java 平台上运行。Jython 程序可以导入和使用任何 Java 类。就像 Java 一样,Jython 程序编译为字节码。主要优点之一是用 Python 设计的用户界面可以使用AWTSwingSWT 包的 GUI 元素。

Jython 最初名为 JPython,后来重命名,它严格遵循由Guido Van Rossum创建的称为CPython的标准 Python 实现。Jython 由Jim Hugunin于 1997 年创建。Jython 2.0 于 1999 年发布。从那时起,Jython 2.x 版本对应于等效的 CPython 版本。Jython 2.7.0 于 2015 年 5 月发布,对应 CPython 2.7。Jython 3.x 的开发正在进行中。

Python 和 Java 的区别

以下是 Python 和 Java 之间的区别 -

  • Python 是一种动态类型语言。因此,不需要变量的类型声明。另一方面,Java 是一种静态类型语言,这意味着变量的类型声明是强制性的并且不能更改。

  • Python 仅具有未检查异常,而 Java 则同时具有检查异常和未检查异常。

  • Python 使用缩进来确定范围,而 Java 使用匹配的花括号。

  • 由于Python是一种基于解释器的语言,因此它没有单独的编译步骤。然而,Java 程序需要编译为字节码,然后由 JVM 执行。

  • Python支持多重继承,但在Java中,多重继承是不可能的。然而它有一个接口的实现。

  • 与Java相比,Python具有更丰富的内置数据结构(列表、字典、元组,一切都是对象)。

Python 和 Jython 之间的区别

以下是 Python 和 Jython 之间的区别 -

  • Python 的参考实现称为 CPython,是用 C 语言编写的。另一方面,Jython 完全用 Java 编写,是 JVM 实现。

  • 标准 Python 可在多个平台上使用。Jython 可用于安装了 JVM 的任何平台。

  • 标准 Python 代码编译为.pyc文件,而 Jython 程序编译为.class文件。

  • Python 扩展可以用 C 语言编写。Jython 的扩展是用 Java 编写的。

  • Jython 本质上是真正的多线程。然而,Python 使用全局解释器锁(GIL) 机制来实现此目的。

  • 两种实现都有不同的垃圾收集机制。

在下一章中,我们将学习如何在 Jython 中导入 Java 库。

Jython - 安装

在安装 Jython 2.7 之前,请确保系统已安装JDK 7或更高版本。Jython 以可执行 jar 文件的形式提供。从 - http://www.jython.org/downloads.html下载它,然后双击其图标或运行以下命令 -

java -jar jython_installer-2.7.0.jar

安装向导将启动,其中必须提供安装选项。以下是系统安装过程。

向导的第一步要求您选择语言。

向导

第二步提示您接受许可协议。

许可协议

在下一步中,选择安装类型。建议选择标准安装。

安装类型

下一个屏幕会要求您确认您的选项,然后继续完成安装。

概述

安装过程可能需要一些时间才能完成。

安装正在进行中

安装完成后,从目标目录内的 bin 目录中调用jython.exe 。假设 Jython 安装在C:\jython27中,从命令行执行以下命令。

C:\jython27\bin\jython

将出现Python提示符(>>>),在其前面可以执行任何Python语句或Python脚本。

Python提示符

Jython - 导入 Java 库

Jython 最重要的功能之一是它能够在 Python 程序中导入 Java 类。我们可以在 Jython 中导入任何 java 包或类,就像在 Java 程序中一样。以下示例显示如何在 Python (Jython) 脚本中导入java.util包以声明 Date 类的对象。

from java.util import Date
d = Date()
print d

将上述代码保存为UtilDate.py并从命令行运行。将显示当前日期和时间的实例。

C:\jython27\bin>jython UtilDate.py
Sun Jul 09 00:05:43 IST 2017

Java 库中的以下包更常被导入到 Jython 程序中,主要是因为标准 Python 库要么没有等效项,要么不那么好。

  • 小服务程序
  • 联合管理系统
  • J2EE
  • Java文档
  • Swing 被认为优于其他 GUI 工具包

任何与此相关的 Java 包都可以导入到 Jython 脚本中。这里,以下 java 程序存储并编译在名为foo的包中。

package foo;
public class HelloWorld {
   public void hello() {
      System.out.println("Hello World!");
   }
   public void hello(String name) {
      System.out.printf("Hello %s!", name);
   }
}

HelloWorld.class导入到以下 Jython 脚本中。可以从 Jython 脚本importex.py调用此类中的方法。

from foo import HelloWorld
h = HelloWorld()
h.hello()
h.hello("TutorialsPoint")

保存并从命令行执行上述脚本以获得以下输出。

C:\jython27\bin>jython importex.py
Hello World!
Hello TutorialsPoint!

Jython - 变量和数据类型

变量是计算机内存中的命名位置。每个变量可以保存一条数据。与 Java 不同,Python 是一种动态类型语言。因此,在使用 Jython 时;未事先声明变量的数据类型。不是变量的类型决定其中可以存储哪些数据,而是数据决定变量的类型。

在以下示例中,为变量分配了整数值。使用 type() 内置函数,我们可以验证变量的类型是否为整数。但是,如果为同一个变量分配了一个字符串,则 type() 函数会将字符串作为同一变量的类型。

> x = 10
>>> type(x)
<class 'int'>

>>> x = "hello"
>>> type(x)
<class 'str'>

这解释了为什么Python被称为动态类型语言。

以下 Python 内置数据类型也可以在 Jython 中使用 -

  • 数字
  • 细绳
  • 列表
  • 元组
  • 字典

Python 将数值数据识别为数字,可以是整数、带浮点数的实数或复数。字符串、列表和元组数据类型称为序列。

Jython 数字

在 Python 中,任何有符号整数都被称为“int”类型。为了表示长整数,在其后面附加字母“L”。用小数点分隔整数部分和小数部分的数字称为“浮点数”。小数部分可以包含使用“E”或“e”以科学计数法表示的指数。

在 Python 中,复数也被定义为数字数据类型。复数包含一个实部(浮点数)和一个附有“j”的虚部。

为了以八进制或十六进制表示形式表达数字,在其前面添加0O0X 。以下代码块给出了 Python 中数字的不同表示形式的示例。

int     -> 10, 100, -786, 80
long    -> 51924361L, -0112L, 47329487234L
float   -> 15.2, -21.9, 32.3+e18, -3.25E+101
complex -> 3.14j, 45.j, 3e+26J, 9.322e-36j

Jython 字符串

字符串是用单引号(例如“hello”)、双引号(例如“hello”)或三引号(例如““hello””或“““hello”””)括起来的任何字符序列。如果字符串的内容跨越多行,三引号特别有用。

转义序列字符可以逐字包含在三重引号字符串中。以下示例展示了在 Python 中声明字符串的不同方法。

str = ’hello how are you?’
str = ”Hello how are you?”
str = """this is a long string that is made up of several lines and non-printable
characters such as TAB ( \t ) and they will show up that way when displayed. NEWLINEs
within the string, whether explicitly given like this within the brackets [ \n ], or just
a NEWLINE within the variable assignment will also show up.
"""

打印第三个字符串时,将给出以下输出。

this is a long string that is made up of
several lines and non-printable characters such as
TAB ( 	 ) and they will show up that way when displayed.
NEWLINEs within the string, whether explicitly given like
this within the brackets [
], or just a NEWLINE within
the variable assignment will also show up.

Jython 列表

列表是一种序列数据类型。它是用逗号分隔的项目的集合,不一定是同一类型,存储在方括号中。可以使用从零开始的索引来访问列表中的单个项目。

以下代码块总结了 Python 中列表的用法。

list1 = ['physics', 'chemistry', 1997, 2000];
list2 = [1, 2, 3, 4, 5, 6, 7 ];
print "list1[0]: ", list1[0]
print "list2[1:5]: ", list2[1:5]

下表描述了与 Jython 列表相关的一些最常见的 Jython 表达式。

Jython 表达式 描述
长度(列表) 长度
列表[2]=10 更新
删除列表[1] 删除
列表.追加(20) 附加
列表.插入(1,15) 插入
列表.sort() 排序

Jython 元组

元组是存储在括号中的逗号分隔数据项的不可变集合。无法删除或修改元组中的元素,也无法将元素添加到元组集合中。以下代码块显示了元组操作。

tup1 = ('physics','chemistry‘,1997,2000);
tup2 = (1, 2, 3, 4, 5, 6, 7 );
print "tup1[0]: ", tup1[0]
print "tup2[1:5]: ", tup2[1:5]

Jython 词典

Jython Dictionary 类似于 Java Collection 框架中的 Map 类。它是键值对的集合。以逗号分隔的对括在大括号中。Dictionary 对象不遵循基于零的索引来检索其中的元素,因为它们是通过哈希技术存储的。

同一键在字典对象中不能出现多次。然而,多个键可以具有相同的关联值。Dictionary 对象可用的不同功能解释如下 -

dict = {'011':'New Delhi','022':'Mumbai','033':'Kolkata'}
print "dict[‘011’]: ",dict['011']
print "dict['Age']: ", dict['Age']

下表描述了与字典相关的一些最常见的 Jython 表达式。

Jython 表达式 描述
dict.get('011') 搜索
长度(字典) 长度
dict['044'] = '钦奈' 附加
删除字典['022'] 删除
字典.keys() 键列表
字典.values() 值列表
dict.clear() 删除所有元素

Jython - 使用 Java 集合类型

除了 Python 的内置数据类型之外,Jython 还具有通过导入java.util 包来使用 Java 集合类的优点。以下代码描述了下面给出的类 -

  • Java ArrayList 对象与 add()
  • 消除()
  • ArrayList 类的 get() 和 set() 方法。
import java.util.ArrayList as ArrayList
arr = ArrayList()
arr.add(10)
arr.add(20)
print "ArrayList:",arr
arr.remove(10) #remove 10 from arraylist
arr.add(0,5) #add 5 at 0th index
print "ArrayList:",arr
print "element at index 1:",arr.get(1) #retrieve item at index 1
arr.set(0,100) #set item at 0th index to 100
print "ArrayList:",arr

上述 Jython 脚本产生以下输出 -

C:\jython27\bin>jython arrlist.py
ArrayList: [10, 20]
ArrayList: [5, 20]
element at index 1: 20
ArrayList: [100, 20]

杰瑞级

Jython 还实现了Jarray Object,它允许在 Python 中构造 Java 数组。为了使用 jarray,只需在 Jython 中定义一个序列类型并将其与序列中包含的对象类型一起传递给 jarrayobject。jar 数组中的所有值必须属于同一类型。

下表显示了与 jarray 一起使用的字符类型代码。

字符类型代码 对应的Java类型
Z 布尔值
C 字符
字节
H 短的
整数
L 长的
F 漂浮
D 双倍的

下面的例子展示了 jarray 的构建。

my_seq = (1,2,3,4,5)
from jarray import array
arr1 = array(my_seq,'i')
print arr1
myStr = "Hello Jython"
arr2 = array(myStr,'c')
print arr2

这里my_seq被定义为整数元组。它被转换为 Jarray arr1。第二个示例显示 Jarray arr2 是根据mySttr 字符串序列构造的。上述脚本jarray.py的输出如下 -

array('i', [1, 2, 3, 4, 5])
array('c', 'Hello Jython')

Jython - 决策控制

决策结构具有由程序评估或测试的一个或多个条件,以及如果确定条件为真则要执行的一个或多个语句,以及可选地,如果条件确定则要执行的其他语句确定为假。

下图显示了大多数编程语言中典型决策结构的一般形式 -

决策控制

Jython 不使用大括号来指示条件为 true 或 false 时要执行的语句块(如 Java 中的情况)。相反,使用统一缩进(左侧空白)来形成语句块。这种统一缩进的块使得当“if”语句中给出的条件为真时执行条件代码。

在可选的“else”语句之后可能会出现类似的块。Jython 还提供了elif 语句,使用该语句可以测试连续条件。这里,else 子句将出现在最后,只有当前面的条件全部失败时才会执行。使用if..elif..else的一般语法如下。

if expression1:
   statement(s)
elif expression2:
   statement(s)
elif expression3:
   statement(s)
else:
   statement(s)

在以下示例中, if ..elif ..else构造用于计算用户输入的不同金额值的折扣。

discount = 0
amount = input("enter Amount")
if amount>1000:
   discount = amount*0.10
elif amount>500:
   discount = amount*0.05
else:
   discount = 0
print 'Discount = ',discount
print 'Net amount = ',amount-discount

上述代码的输出如下所示。

enter Amount1500
Discount = 150.0
Net amount = 1350.0
enter Amount600
Discount = 30.0
Net amount = 570.0
enter Amount200
Discount = 0
Net amount = 200

Jython - 循环

一般来说,程序中的语句是按顺序执行的:首先执行函数中的第一个语句,然后执行第二个语句,依此类推。可能存在这样的情况:您需要多次执行一段代码。提供这种重复能力的语句称为循环语句

在 Jython 中,循环可以由两条语句形成,它们是 -

  • while语句

  • for语句_

WHILE 循环

Jython 中的 while 循环语句与 Java 中的类似。只要给定条件为真,它就会重复执行语句块。以下流程图描述了while循环的Behave。

While 循环

while 语句的一般语法如下所示。

while expression:
   statement(s)

以下 Jython 代码使用 while 循环重复递增并打印变量的值,直到该值小于零。

count = 0
while count<10:
   count = count+1
   print "count = ",count
print "Good Bye!"

输出- 输出如下。

count =  1
count =  2
count =  3
count =  4
count =  5
count =  6
count =  7
count =  8
count =  9
count =  10
Good Bye!

FOR 循环

Jython 中的 FOR 循环不像 Java 中那样是计数循环。相反,它能够遍历序列数据类型(例如字符串、列表或元组)中的元素。Jython 中 FOR 语句的一般语法如下所示 -

for iterating_var in sequence:
   statements(s)

我们可以使用 FOR 语句显示字符串中的每个字符以及列表或元组中的每个项目,如下所示 -

#each letter in string
for letter in 'Python':
   print 'Current Letter :', letter

输出- 输出如下。

Current Letter : P
Current Letter : y
Current Letter : t
Current Letter : h
Current Letter : o
Current Letter : n

让我们考虑另一个例子如下。

#each item in list
libs = [‘PyQt’, 'WxPython',  'Tkinter']
for lib in libs:        # Second Example
   print 'Current library :', lib

输出- 输出如下。

Current library : PyQt
Current library : WxPython
Current library : Tkinter

这是另一个需要考虑的例子。

#each item in tuple
libs = (‘PyQt’, 'WxPython',  'Tkinter')
for lib in libs:        # Second Example
   print 'Current library :', lib

输出- 上述程序的输出如下。

Current library : PyQt
Current library : WxPython
Current library : Tkinter

在 Jython 中,for语句还用于迭代 range() 函数生成的数字列表。range() 函数采用以下形式 -

range[([start],stop,[step])

start 和 step 参数默认为 0 和 1。最后生成的数字是停止步骤。FOR 语句遍历由range() 函数形成的列表。例如 -

for num in range(5):
   print num

它产生以下输出 -

0
1
2
3
4

Jython - 函数

复杂的编程逻辑被分解为一个或多个独立且可重用的语句块,称为函数。Python的标准库包含大量的内置函数。人们还可以使用def关键字定义自己的函数。用户定义的函数名称后面跟着形成其主体的语句块,该语句块以 return 语句结尾。

一旦定义,就可以从任何环境中调用它任意次。让我们考虑下面的代码来阐明这一点。

#definition of function
defSayHello():
   "optional documentation string"
   print "Hello World"
   return

#calling the function
SayHello()

函数可以设计为从调用环境接收一个或多个形参/自变量。在调用此类参数化函数时,您需要提供与函数定义中使用的相同数量且具有相似数据类型的参数,否则 Jython 解释器将引发 TypeError异常

例子

#defining function with two arguments
def area(l,b):
   area = l*b
   print "area = ",area
   return

#calling function
length = 10
breadth = 20
#with two arguments. This is OK
area(length, breadth)
#only one argument provided. This will throw TypeError
area(length)

输出如下-

area = 200
Traceback (most recent call last):
   File "area.py", line 11, in <module>
   area(length)
TypeError: area() takes exactly 2 arguments (1 given)

执行其中定义的步骤后,被调用函数返回到调用环境。如果函数定义中的 return 关键字前面提到了表达式,则它可以返回数据。

#defining function
def area(l,b):
   area = l*b
   print "area = ",area
   return area

#calling function
length = 10
breadth = 20
#calling function and obtaining its reurned value
result = area(length, breadth)
print "value returned by function : ", result

如果从 Jython 提示符执行上述脚本,将获得以下输出。

area = 200
value returned by function : 200

Jython - 模块

模块是一种 Jython 脚本,其中定义了一个或多个相关函数、类或变量。这允许对 Jython 代码进行逻辑组织。通过从模块导入模块或特定元素(函数/类),可以在另一个 Jython 脚本中使用模块中定义的程序元素。

在以下代码 (hello.py) 中定义了函数SayHello() 。

#definition of function
defSayHello(str):
   print "Hello ", str
   return

要使用另一个脚本中的 SayHello() 函数,请在其中导入hello.py 模块。

import hello
hello.SayHello("TutorialsPoint")

但是,这将导入模块中定义的所有函数。为了从模块导入特定函数,请使用以下语法。

from modname import name1[, name2[,... nameN]

例如,要仅导入 SayHello() 函数,请将上面的脚本更改如下。

from hello import SayHello
SayHello("TutorialsPoint")

调用函数时无需添加模块名称前缀。

Jython - 包

任何包含一个或多个 Jython 模块的文件夹都被识别为一个包。但是,它必须有一个名为__init__.py的特殊文件,它提供要使用的函数的索引。

现在让我们了解如何创建和导入包。

步骤 1 - 创建一个名为package1的文件夹,然后在其中创建并保存以下g模块。

#fact.py
def factorial(n):
   f = 1
   for x in range(1,n+1):
      f = f*x
   return f

#sum.py
def add(x,y):
   s = x+y
   return s

#mult.py
def multiply(x,y):
   s = x*y
   return s

步骤 2 - 在 package1 文件夹中创建并保存包含以下内容的__init__.py文件。

#__init__.py
from fact import factorial
from sum import add
from mult import multiply

步骤 3 - 在 package1 文件夹外部创建以下 Jython 脚本作为test.py

# Import your Package.
import package1

f = package1.factorial(5)
print "factorial = ",f
s = package1.add(10,20)
print "addition = ",s
m = package1.multiply(10,20)
print "multiplication = ",m

步骤 4 - 从 Jython 提示符执行 test.py。将获得以下输出。

factorial = 120
addition = 30
multiplication = 200

Jython - Java 应用程序

下载jython-standalone-2.7.0.jar - 用于从官方下载页面将 Jython 嵌入 Java 应用程序:http://www.jython.org/downloads.html并将此 jar 文件包含在 Java CLASSPATH 环境变量中。

该库包含PythonInterpreter类。使用此类的对象,可以使用execfile()方法执行任何 Python 脚本。PythonInterpreter 使您能够直接使用PyObjects。Jython 运行时系统已知的所有对象均由 PyObject 类或其子类之一的实例表示。

PythonInterpreter 类有一些常用的方法,下表对此进行了解释。

先生。 方法及说明
1

设置(PyObject)

设置用于标准输入流的 Python 对象

2

setIn(java.io.Reader)

设置用于标准输入流的 java.io.Reader

3

setIn(java.io.InputStream)

设置用于标准输入流的 java.io.InputStream

4

setOut(PyObject)

设置用于标准输出流的 Python 对象

5

setOut(java.io.Writer)

设置用于标准输出流的 java.io.Writer

6

setOut(java,io.OutputStream)

设置用于标准输出流的 java.io.OutputStream

7

设置错误(PyObject)

设置用于标准错误流的 Python 错误对象

8

setErr(java.io.Writer)

设置用于标准错误流的 java.io.Writer

9

setErr(java.io.OutputStream)

设置用于标准错误流的 java.io.OutputStream

10

评估(字符串)

将字符串作为 Python 源进行计算并返回结果

11

评估(PyObject)

评估 Python 代码对象并返回结果

12

执行(字符串)

在本地命名空间中执行Python源字符串

13

执行(PyObject)

在本地命名空间中执行Python代码对象

14

execfile(字符串文件名)

在本地命名空间中执行Python源文件

15

execfile(java.io.InputStream)

在本地命名空间中执行Python源的输入流

16

编译(字符串)

将 Python 源字符串编译为表达式或模块

17 号

编译(脚本,文件名)

将 Python 源代码编译为表达式或模块

18

设置(字符串名称,对象值)

在本地命名空间中设置一个Object类型的变量

19

设置(字符串名称,PyObject 值)

在本地命名空间中设置一个 PyObject 类型的变量

20

获取(字符串)

获取本地命名空间中变量的值

21

获取(字符串名称,类java类

获取本地命名空间中变量的值。该值将作为给定 Java 类的实例返回。

以下代码块是一个 Java 程序,具有嵌入的 Jython 脚本“hello.py”.usingexecfile() PythonInterpreter 对象的方法。它还展示了如何使用 set() 和 get() 方法设置或读取 Python 变量。

import org.python.util.PythonInterpreter;
import org.python.core.*;

public class SimpleEmbedded {
   public static void main(String []args) throws PyException {
      PythonInterpreter interp = new PythonInterpreter();
      System.out.println("Hello, world from Java");
      interp.execfile("hello.py");
      interp.set("a", new PyInteger(42));
      interp.exec("print a");
      interp.exec("x = 2+2");
      PyObject x = interp.get("x");
      System.out.println("x: "+x);
      System.out.println("Goodbye ");
   }
}

编译并运行上述Java程序,得到如下输出。

Hello, world from Java
hello world from Python
42
x: 4
Goodbye

Jython - Eclipse 插件

PyDev 是 Eclipse IDE 的开源插件,支持使用 Python、Jython 以及 IronPython 进行项目开发。它托管在https://pydev.org。下面给出了在 Eclipse IDE 中安装 PyDev 插件的分步过程。

步骤 1 - 打开 Eclipse IDE 并从“帮助”菜单中选择“安装新软件”选项。

安装新软件

步骤 2 -在使用标签前面的文本框中输入http://pydev.org/updates并单击添加。选择列表中的所有可用条目,然后单击“下一步”。向导将需要几分钟时间来完成安装,并且会提示 IDE 重新启动。

可用软件

步骤 3 - 现在从窗口菜单中选择首选项选项。首选项对话框将打开,如下所示。

优先

步骤 4 - 展开解释器节点并在左侧窗格中选择 Jython 解释器。在右侧窗格中,单击“新建”以提供jython.jar 文件的路径。

Jython 罐子

现在我们已准备好使用 Eclipse 启动 Jython 项目。

Jython - Eclipse 中的项目

要在 eclipse 中创建一个项目,我们应该按照下面给出的步骤操作。

步骤 1 - 选择文件?新的 ?项目。从过滤器对话框中选择PyDev 。提供项目名称、项目类型,然后单击“完成”。

派德

步骤 2 - Hello 项目现在将出现在左侧的项目资源管理器中。右键添加hello.py进去。

你好

步骤 3 - 编辑器中将出现一个空的 hello.py。编写 Jython 代码并保存。

空哈喽

步骤 4 - 单击菜单栏上的“运行”按钮。输出将显示在控制台窗口中,如下所示。

运行按钮

Jython - NetBeans 插件和项目

可通过nbPython 插件获得对 NetBeans 的 Python 和 Jython 支持。从以下 URL 下载插件 - http://plugins.netbeans.org/plugin/56795。将下载的存档解压缩到某个文件夹中。例如 - d:\nbplugin。要安装 NetBeans 插件,请按照以下步骤操作。

步骤 1 - 启动Netbeans IDE,然后转到“工具/插件”以打开插件管理器。选择“已下载”选项卡并浏览到下载文件已解压缩的文件夹。NetBeans 窗口将出现,如下所示。

Netbeans 集成开发环境

步骤 2 - 下一步是选择所有.nbm文件并单击打开。

NBM

步骤 3 - 单击“安装”按钮。

安装按钮

步骤 4 - 接受以下许可协议以继续。

协议

忽略有关插件来源不受信任的警告并重新启动 IDE 以继续。

NetBeans 中的 Jython 项目

重新启动后,通过选择“文件/新建”启动新项目。Python 类别现在将在类别列表中可用。选择它继续。

类别

如果系统安装了Python,则会自动检测其版本并显示在Python平台下拉列表中。但是,Jython 将不会被列出。单击“管理”按钮进行添加。

Python

单击“新建”按钮添加平台名称和 Jython 可执行文件的路径。

Jython 可执行文件

Jython 现在将出现在平台列表中。从下拉列表中选择,如以下屏幕截图所示。

下拉列表

现在我们可以在下一个窗口中填写项目名称、位置和主文件。

项目名

项目结构将显示在 NetBeans IDE 的项目窗口中,并且模板 Python 代码将显示在编辑器窗口中。

项目窗口

模板 Python 代码

构建并执行 Jython 项目,在 NetBeans IDE 的输出窗口中获得以下结果。

输出窗口

Jython - Servlet

Java servlet 是最广泛使用的 Web 开发技术。我们可以使用 Jython 来编写 servlet,这增加了 Java 所能提供的更多优势,因为现在我们也可以利用 Python 语言功能。

我们将使用 NetBeans IDE 来开发带有 Jython servlet 的 Java Web 应用程序。确保NetBeans 安装中安装了nbPython 插件。通过选择以下路径启动一个新项目来构建 Web 应用程序 - File → New Project → Java web → New Web Application

提供项目名称和位置。IDE 将创建项目文件夹结构。在“项目”窗口中的源包节点下添加 Java servlet 文件 (ServletTest.java)。这将在项目的 lib 文件夹中添加servlet-api.jar 。另外,让 IDE 创建 web.xml描述符文件在ServletTest.java中添加以下代码。

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ServletTest extends HttpServlet {
   
   public void doGet (HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
      doPost(request, response);
   }
   
   public void doPost (HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
      response.setContentType ("text/html");
      PrintWriter toClient = response.getWriter();
      
      toClient.println (
         "<html>
            <head>
               <title>Servlet Test</title>" + "
            </head>
            <body>
               <h1>Servlet Test</h1>
            </body>
         </html>"
      );
   }
}

NetBeans 创建的 web.xml 文件如下所示 -

<web-app>
   <servlet>
      <servlet-name>ServletTest</servlet-name>
      <servlet-class>ServletTest</servlet-class>
   </servlet>
   
   <servlet-mapping>
      <servlet-name>ServletTest</servlet-name>
      <url-pattern>/ServletTest</url-pattern>
   </servlet-mapping>
</web-app>

构建并运行该项目,以获得浏览器窗口中 <h1> 标记中出现的文本Servlet Test 。因此,我们在应用程序中添加了常规 Java servlet。

现在,我们将添加 Jython Servlet。Jython servlet 通过中间 Java servlet(也称为 PyServlet)工作。PyServlet.class 存在于jythonstandalone.jar中。将其添加到WEB-INF/lib文件夹中。

下一步是配置 web.xml 以在每当发出对任何*.py 文件的请求时调用 PyServlet 。这应该通过在其中添加以下 xml 代码来完成。

<servlet>
   <servlet-name>PyServlet</servlet-name>
   <servlet-class>org.python.util.PyServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
   <servlet-name>PyServlet</servlet-name>
   <url-pattern>*.py</url-pattern>
</servlet-mapping>

完整的 web.xml 代码如下所示。

<web-app>
   <servlet>
      <servlet-name>ServletTest</servlet-name>
      <servlet-class>ServletTest</servlet-class>
   </servlet>
   
   <servlet>
      <servlet-name>PyServlet</servlet-name>
      <servlet-class>org.python.util.PyServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
   </servlet>
   
   <servlet-mapping>
      <servlet-name>ServletTest</servlet-name>
      <url-pattern>/ServletTest</url-pattern>
   </servlet-mapping>
   
   <servlet-mapping>
      <servlet-name>PyServlet</servlet-name>
      <url-pattern>*.py</url-pattern>
   </servlet-mapping>
</web-app>

将以下 Jython 代码作为 JythonServlet.py 放置在项目文件夹内的 WEB-INF 文件夹中,这相当于前面的 ServletTest.java。

from javax.servlet.http import HttpServlet
class JythonServlet1 (HttpServlet):
   def doGet(self,request,response):
      self.doPost (request,response)
   def doPost(self,request,response):
      toClient = response.getWriter()
      response.setContentType ("text/html")
      
      toClient.println (
         "<html>
            <head>
               <title>Servlet Test</title>" + "
            </head>
            <body>
               <h1>Servlet Test</h1>
            </body>
         </html>"
      )

构建项目并在浏览器中打开以下 URL -

http://localhost:8080/jythonwebapp/jythonservlet.py

浏览器将在 <h1> 标记中显示Servlet 测试,就像 Java Servlet 输出一样。

Jython-JDBC

Jython 使用zxJDBC 包,该包提供了一个易于使用的 JDBC 周围的 Python 包装器。zxJDBC桥接了两个标准:JDBC是Java中数据库访问的标准平台,DBI是Python应用程序的标准数据库API。

ZxJDBC 提供了符合 DBI 2.0 标准的 JDBC 接口。超过 200 个驱动程序可用于 JDBC,它们都可以与 zxJDBC 配合使用。高性能驱动程序可用于所有主要关系数据库,包括 -

  • 数据库2
  • 德比
  • MySQL
  • 甲骨文
  • PostgreSQL
  • SQLite
  • SQL 服务器和
  • 赛贝斯。

ZxJDBC包可以从https://sourceforge.net/projects/zxjdbc/http://www.ziclix.com/zxjdbc/下载。下载的存档包含 ZxJDBC.jar,应将其添加到 CLASSPATH 环境变量中。

我们打算与MySQL数据库建立数据库连接。为此,需要 MySQL 的 JDBC 驱动程序。从以下链接下载MySQL J 连接器- https://dev.mysql.com/downloads/connector/j/并将 mysql 连接器 java-5.1.42-bin.jar 包含在 CLASSPATH 中。

登录到 MySQL 服务器并在测试数据库中创建一个学生表,其结构如下 -

场地 类型 宽度
姓名 瓦尔查尔 10
年龄 INT 3
分数 INT 3

在其中添加一些记录。

姓名 年龄 分数
拉维 21 78
阿肖克 20 65
阿尼尔 22 71

创建以下 Jython 脚本作为dbconnect.py

url = "jdbc:mysql://localhost/test"
user = "root"
password = "password"
driver = "com.mysql.jdbc.Driver"
mysqlConn = zxJDBC.connect(url, user, password, driver)
mysqlConn = con.cursor()
mysqlConn.execute(“select * from student)
for a in mysql.fetchall():
   print a

从 Jython 提示符执行上述脚本。学生表中的记录将如下所示列出 -

(“Ravi”, 21, 78)
(“Ashok”, 20, 65)
(“Anil”,22,71)

这解释了在 Jython 中建立 JDBC 的过程。

Jython - 使用 Swing GUI 库

Jython 的主要功能之一是它能够使用 JDK 中的 Swing GUI 库。标准 Python 发行版(通常称为 CPython)附带了Tkinter GUI 库。其他 GUI 库(如PyQtWxPython)也可以与它一起使用,但 swing 库提供了一个独立于平台的 GUI 工具包。

与在 Java 中使用相比,在 Jython 中使用 swing 库要容易得多。在 Java 中,必须使用匿名类来创建事件绑定。在 Jython 中,我们可以简单地传递一个函数来达到相同的目的。

基本的顶层窗口是通过声明JFrame 类的对象并将其visible属性设置为true来创建的。为此,需要从 swing 包中导入 Jframe 类。

from javax.swing import JFrame

JFrame 类有多个带有不同数量参数的构造函数。我们将使用一个,它接受一个字符串作为参数并将其设置为标题。

frame = JFrame(“Hello”)

在将其可见属性设置为 true 之前,先设置框架的大小和位置属性。将以下代码存储为frame.py

from javax.swing import JFrame

frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(300,200)
frame.setVisible(True)

从命令提示符运行上述脚本。它将显示以下输出并显示一个窗口。

窗户

swing GUI 库以 Java 中的javax.swing包的形式提供。它的主要容器类JFrameJDialog分别派生自AWT库中的Frame和Dialog类。其他 GUI 控件(如JLabel、JButton、JTextField等)均派生自 JComponent 类。

下图显示了 Swing 包类层次结构。

Swing 包类层次结构

下表总结了 swing 库中不同的 GUI 控制类 -

先生。 类别和描述
1

J标签

JLabel 对象是用于将文本放置在容器中的组件。

2

J按钮

此类创建一个带标签的按钮。

3

J颜色选择器

JColorChooser 提供了一个控件窗格,旨在允许用户操作和选择颜色。

4

复选框

JCheckBox 是一个图形组件,可以处于打开(true) 或关闭(false) 状态。

5

J单选按钮

JRadioButton 类是一个图形组件,可以处于打开 (true) 或关闭 (false) 状态。在一组。

6

列表

JList 组件向用户呈现文本项的滚动列表。

7

J组合框

JComboBox 组件向用户呈现项目的下拉列表

8

文本字段

JTextField 对象是一个文本组件,允许编辑单行文本。

9

J密码字段

JPasswordField 对象是专门用于密码输入的文本组件。

10

文本区

JTextArea 对象是一个文本组件,允许编辑多行文本。

11

图像图标

ImageIcon 控件是 Icon 接口的实现,可从图像绘制图标

12

JScrollbar

滚动条控件表示滚动条组件,以便用户能够从值范围中进行选择。

13

J选项面板

JOptionPane 提供了一组标准对话框,提示用户输入值或通知他们某些信息。

14

文件选择器

JFileChooser 控件代表一个对话框窗口,用户可以从中选择文件。

15

J进度条

随着任务逐渐完成,进度条会显示任务的完成百分比。

16

JS滑块

JSlider 允许用户通过在有限的间隔内滑动旋钮来以图形方式选择一个值。

17 号

JSpinner

JSpinner 是一个单行输入字段,允许用户从有序序列中选择数字或对象值。

我们将在后续示例中使用其中一些控件。

Jython - 布局管理

Java 中的布局管理器是那些管理容器对象(如Frame、DialogPanel)中控件的放置的类。即使分辨率发生变化或框架本身大小发生调整,布局管理器也会保持框架中控件的相对位置。

这些类实现Layout 接口AWT 库中定义了以下布局管理器-

  • 边框布局
  • 流式布局
  • 网格布局
  • 卡片布局
  • 网格包布局

Swing 库中定义了以下布局管理器-

  • 盒子布局
  • 组布局
  • 滚动窗格布局
  • Spring布局

在下面的示例中,我们将使用 AWT 布局管理器以及 swing 布局管理器。

  • 绝对布局
  • 流程布局
  • 网格布局
  • 边框布局
  • 盒子布局
  • 集团布局

现在让我们详细讨论其中的每一个。

绝对布局

在探索上述所有布局管理器之前,我们必须了解容器中控件的绝对定位。我们必须将框架对象的布局方法设置为“无”。

frame.setLayout(None)

然后通过调用setBounds()方法放置控件。它有四个参数 - x 位置、y 位置、宽度和高度。

例如 - 将按钮对象放置在绝对位置并具有绝对大小。

btn = JButton("Add")
btn.setBounds(60,80,60,20)

同样,所有控件都可以通过正确分配位置和大小来放置。此布局相对易于使用,但当调整窗口大小或在屏幕分辨率更改时执行程序时,无法保留其外观。

在以下 Jython 脚本中,三个 Jlabel 对象分别用于显示文本“phy”、“maths”和“Total”。在这三个 - JTextField 对象的前面放置。Button 对象放置在“Total”标签上方。

首先,创建 JFrame 窗口,并将布局设置为 none。

frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(300,200)
frame.setLayout(None)

然后根据其绝对位置和大小添加不同的控件。完整的代码如下 -

from javax.swing import JFrame, JLabel, JButton, JTextField

frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(300,200)
frame.setLayout(None)

lbl1 = JLabel("Phy")
lbl1.setBounds(60,20,40,20)
txt1 = JTextField(10)
txt1.setBounds(120,20,60,20)
lbl2 = JLabel("Maths")
lbl2.setBounds(60,50,40,20)
txt2 = JTextField(10)
txt2.setBounds(120, 50, 60,20)
btn = JButton("Add")
btn.setBounds(60,80,60,20)
lbl3 = JLabel("Total")
lbl3.setBounds(60,110,40,20)
txt3 = JTextField(10)
txt3.setBounds(120, 110, 60,20)

frame.add(lbl1)
frame.add(txt1)
frame.add(lbl2)
frame.add(txt2)
frame.add(btn)
frame.add(lbl3)
frame.add(txt3)
frame.setVisible(True)

上述代码的输出如下。

添加

Jython FlowLayout

FlowLayout 是容器类的默认布局管理器。它从左到右,然后从上到下方向排列控制。

在以下示例中,将使用 FlowLayout 管理器在 JFrame 中显示 Jlabel 对象、JTextField 对象和 JButton 对象。首先,让我们从javax.swing包和java.awt包中导入所需的类。

from javax.swing import JFrame, JLabel, JButton, JTextField
from java.awt import FlowLayout

然后创建一个 JFrame 对象并设置其位置和大小属性。

frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(200,200)
Set the layout manager for the frame as FlowLayout.
frame.setLayout(FlowLayout())

现在声明 JLabel、JTextfield 和 JButton 类的对象。

label = JLabel("Welcome to Jython Swing")
txt = JTextField(30)
btn = JButton("ok")

最后通过调用JFrame 类的add()方法将这些控件添加到框架中。

frame.add(label)
frame.add(txt)
frame.add(btn)

要显示框架,请将其可见属性设置为 true。完整的 Jython 脚本及其输出如下所示 -

from javax.swing import JFrame, JLabel, JButton, JTextField
from java.awt import FlowLayout

frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(200,200)

frame.setLayout(FlowLayout())

label = JLabel("Welcome to Jython Swing")
txt = JTextField(30)
btn = JButton("ok")

frame.add(label)
frame.add(txt)
frame.add(btn)
frame.setVisible(True)
欢迎来到 Jython Swing

Jython 网格布局

网格布局管理器允许将控件放置在矩形网格中。网格的每个单元格中放置一个控件。

在以下示例中,GridLayout 应用于 JFrame 对象,将其分为 4 行和 4 列。JButton 对象将放置在网格的每个单元格中。

让我们首先导入所需的库 -

from javax.swing import JFrame, JButton
from java.awt import GridLayout

然后创建 JFrame 容器 -

frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(400,400)

现在,通过将其尺寸指定为 4 x 4 来应用 GridLayout。

frame.setLayout(GridLayout(4,4))

我们现在应该使用两个 FOR 循环,每个循环从 1 到 4,因此 16 个 JButton 对象被放置在后续单元格中。

k = 0
frame.setLayout(GridLayout(4,4))
for i in range(1,5):
   for j in range(1,5):
      k = k+1
      frame.add(JButton(str(k)))

最后将框架的可见性设置为true。下面给出了完整的 Jython 代码。

from javax.swing import JFrame, JButton
from java.awt import GridLayout

frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(400,400)

frame.setLayout(GridLayout(4,4))

k = 0
for i in range(1,5):
   for j in range(1,5):
      k = k+1
      frame.add(JButton(str(k)))

frame.setVisible(True)

上述代码的输出如下 -

Jython 代码

Jython 边框布局

BorderLayout 管理器将容器划分为五个地理区域,并在每个区域放置一个组件。这些区域由定义的常量表示,如下 -

  • 边框布局.NORTH
  • 边框布局.SOUTH
  • 边框布局.EAST
  • 边框布局.WEST
  • 边框布局.CENTER

让我们考虑以下示例 -

Jython 边框布局

Jython BoxLayout

BoxLayout 类在javax.swing 包中定义。它用于垂直或水平排列容器中的组件。方向由以下常数决定 -

  • X轴
  • Y轴
  • 线轴
  • 页轴

整数常量指定容器组件应沿其布置的轴。当容器具有默认的组件方向时,LINE_AXIS 指定组件从左到右布局,PAGE_AXIS 指定组件从上到下布局。

在以下示例中,面板(JPanel 类)添加到 JFrame 对象中。对其应用了 Vertical BoxLayout,并向其添加了另外两个面板(顶部和底部)。这两个内部面板有两个按钮,每个按钮都添加在水平 Boxlayout 中。

让我们首先创建顶级 JFrame 窗口。

frame = JFrame()
frame.setTitle("Buttons")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setSize(300, 150)

JPanel 对象被声明为具有垂直 BoxLayout。将其添加到顶级框架中。

panel = JPanel()
panel.setLayout(BoxLayout(panel, BoxLayout.Y_AXIS))
frame.add(panel)

在此面板中,添加了两个面板(顶部和底部)。它们中的每一个都水平添加了两个 JButton 对象,并用 25 像素的空间保持器将它们分开。

###top panel
top = JPanel()
top.setLayout(BoxLayout(top, BoxLayout.X_AXIS))
b1 = JButton("OK")
b2 = JButton("Close")
top.add(Box.createVerticalGlue())
top.add(b1)
top.add(Box.createRigidArea(Dimension(25, 0)))
top.add(b2)

类似地,构造底部面板。

###bottom panel
bottom = JPanel()
bottom.setLayout(BoxLayout(bottom, BoxLayout.X_AXIS))
b3 = JButton("Open")
b4 = JButton("Save")
bottom.add(b3)
bottom.add(Box.createRigidArea(Dimension(25, 0)))
bottom.add(b4)
bottom.add(Box.createVerticalGlue())

请注意,createRigidArea()函数用于在两个按钮之间创建 25 像素的空间。createVerticalGlue()函数还占据布局中的前导或尾随空间。

首先,添加顶部和底部面板并将框架的可见性属性设置为 true。完整代码如下 -

from java.awt import Dimension
from javax.swing import JButton, JFrame,JPanel,BoxLayout,Box

frame = JFrame()
frame.setTitle("Buttons")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setSize(300, 150)

panel = JPanel()
panel.setLayout(BoxLayout(panel, BoxLayout.Y_AXIS))
frame.add(panel)

###top panel
top = JPanel()
top.setLayout(BoxLayout(top, BoxLayout.X_AXIS))
b1 = JButton("OK")
b2 = JButton("Close")
top.add(Box.createVerticalGlue())
top.add(b1)
top.add(Box.createRigidArea(Dimension(25, 0)))
top.add(b2)

###bottom panel
bottom = JPanel()
bottom.setLayout(BoxLayout(bottom, BoxLayout.X_AXIS))
b3 = JButton("Open")
b4 = JButton("Save")
bottom.add(b3)
bottom.add(Box.createRigidArea(Dimension(25, 0)))
bottom.add(b4)
bottom.add(Box.createVerticalGlue())

panel.add(bottom)
panel.add(top)
frame.setVisible(True)

上面的代码将生成以下输出。

Jython BoxLayout

Jython 组布局

GroupLayout 管理器以分层方式对组件进行分组。分组是由两个类SequentialGroupParallelGroup完成的,它们都实现了 Java 中的 Group 接口。

布局过程分为两个步骤。第一步,沿水平轴放置组件,第二步沿垂直轴放置。每个组件必须在布局中定义两次。

有两种类型的排列:顺序排列和并行排列。在这两种情况下,我们都可以按顺序或并行排列组件。在水平排列中,行称为顺序组,列称为并行组。另一方面,在并行排列中,行元素是并行的组和列,这称为顺序排列。

在以下示例中,五个按钮的排列方式使得行和列中各出现三个。首先,在 JFrame 窗口中添加一个 Jpanel 对象并将其布局设置为 Grouplayout。

frame =  JFrame()
panel =  JPanel()
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
layout =  GroupLayout(panel)
panel.setLayout(layout)

然后构造 JButton 对象 -

buttonD = JButton("D")
buttonR = JButton("R")
buttonY = JButton("Y")
buttonO = JButton("O")
buttonT = JButton("T")

接下来,我们创建一个名为LeftToRight的SequentialGroup,其中添加了buttonD 和buttonY。在它们之间放置了一个 ParallelGroup ColumnMiddle(垂直添加了其他三个按钮)。

leftToRight = layout.createSequentialGroup()