[雪峰磁针石博客]python与java对接工具Jython介绍

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 模块 退出Python解释器再重新进入,函数和变量等的定义都会丢失。 较大的程序使用文本编辑器编辑的文件作为执行输入更好,即创建脚本。 程序变很长时可将它分割成几个更易于维护的文件。你也可能想在几个程序中使用相同的函数,而不是拷贝代码。

快速入门

下面我们使用jython来调用自定义jar包中的类。

编辑java文件:Beach.java

public class Beach {

    private String name;
    private String city;

    public Beach(String name, String city){
        this.name = name;
        this.city = city;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

}

编译成jar包:

# javac Beach.java 
# echo Main-Class: Beach >manifest.txt
# jar cvfm Craps.jar manifest.txt *.class
已添加清单
正在添加: Beach.class(输入 = 795) (输出 = 430)(压缩了 45%)
正在添加: Point.class(输入 = 708) (输出 = 445)(压缩了 37%)

添加Craps.jar到CLASSPATH,修改/etc/profile,修改CLASSPATH

export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:/usr/local/jython/Craps.jar

使用. /etc/profile导入变量。然后使用jython调用java代码。

# ./jython 
Jython 2.7.0 (default:9987c746f838, Apr 29 2015, 02:25:11) 
[Java HotSpot(TM) 64-Bit Server VM (Oracle Corporation)] on java1.7.0_79
Type "help", "copyright", "credits" or "license" for more information.
>>> import Beach
>>> beach = Beach("Cocoa Beach","Cocoa Beach")
>>> beach.getName()
u'Cocoa Beach'
>>> print beach.getName()
Cocoa Beach
>>>

基础

Linux安装:

# java -jar jython-installer-2.7.0.jar 
# ./jython 
Jython 2.7.0 (default:9987c746f838, Apr 29 2015, 02:25:11) 
[Java HotSpot(TM) 64-Bit Server VM (Oracle Corporation)] on java1.7.0_79
Type "help", "copyright", "credits" or "license" for more information.
>>>

windows安装:双击jython-installer-2.7.0.jar, 执行jython.exe

变量定义:

java
int x = 0;
jython:
x = 0
x = 'Hello Jython'

是动态类型的。

保留字:

and     assert     break     class     continue
def     del     elif     else     except
exec     finally     for     from     global
or     pass     print     raise     return
try     while     with     yield

编码结构使用缩进。

函数名也可以作为函数的参数。

语句关键字:

if-elif-else     for
while     continue
break     try-except-finally
assert     def
print     del
raise     import

文件名和类名一样可以直接导入。

此部分参考资料:

http://www.jython.org/jythonbook/en/1.0/JythonAndJavaIntegration.html

http://www.skylit.com/javamethods/faqs/createjar.html

参考资料:

http://www.jython.org/jythonbook/en/1.0/

模块和包

查看命名空间

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']

Jython的导入不像java那样必须在头部。导入java以右边名优先,python以左边名优先。模块查找路径:

>>> import sys
>>> sys.path
['', '/usr/local/jython2.7.0/Lib', '__classpath__', '__pyclasspath__/', '/usr/local/jython2.7.0/Lib/site-packages']

>>> import sys
>>> sys.path
['', '/usr/local/jython2.7.0/Lib', '__classpath__', '__pyclasspath__/', '/usr/local/jython2.7.0/Lib/site-packages']

>>> import sys
>>> sys.path.append("/home/andrew/code/java/mysql-connector-java-5.1.39/mysql-connector-java-5.1.39-bin.jar")
>>> import com.mysql
*sys-package-mgr*: can't write cache file for '/home/andrew/code/java/mysql-connector-java-5.1.39/mysql-connector-java-5.1.39-bin.jar'
*sys-package-mgr*: can't write index file
>>> dir(com.mysql)
['__name__', 'fabric', 'jdbc']

>>> import java.util.zip
>>> dir(java.util.zip)
['Adler32', 'CRC32', 'CheckedInputStream', 'CheckedOutputStream', 'Checksum', 'DataFormatException', 'Deflater', 'DeflaterInputStream', 'DeflaterOutputStream', 'GZIPInputStream', 'GZIPOutputStream', 'Inflater', 'InflaterInputStream', 'InflaterOutputStream', 'ZipEntry', 'ZipError', 'ZipException', 'ZipFile', 'ZipInputStream', 'ZipOutputStream', '__name__']
>>> dir(java.util.zip.ZipInputStream)
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__doc__', '__ensure_finalizer__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__subclasshook__', '__unicode__', 'available', 'class', 'close', 'closeEntry', 'equals', 'getClass', 'getNextEntry', 'hashCode', 'mark', 'markSupported', 'nextEntry', 'notify', 'notifyAll', 'read', 'reset', 'skip', 'toString', 'wait']

Jython 查找Jar和类的方法:

python.packages.paths
python.packages.directories

java.class.path
java.ext.dirs

python.cachedir.skip

pycimport把python字节码转换成java字节码。Jython导入java包可能有多个包合并。

>>> import sys
>>> sys.path_hooks
[<type 'org.python.core.JavaImporter'>, <type 'zipimport.zipimporter'>,
<type 'ClasspathPyImporter'>]

import pycimport

数据类型

Jython特定的collection,多用于给java传递数据。

# Import and use a Java ArrayList

>>> import java.util.ArrayList as ArrayList

>>> arr = ArrayList()

#  Add method will add an element to the list and return a boolean to signify
successsful addition

>>> arr.add(1)

True

>>> arr.add(2)

True

>>> print arr

[1, 2]

比较老的Jarray,不推荐使用,不过可以创建空数组:

类型:


Character    Java Equivalent
z    boolean
b    byte
c    char
d    Double
f    Float
h    Short
i    Int
l    Long

>>> my_seq = (1,2,3,4,5)

>>> from jarray import array

>>> array(my_seq,'i')

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

>>> myStr = "Hello Jython"

>>> array(myStr,'c')

array('c', 'Hello Jython')

>>> arr = zeros(10,'z')

>>> arr

array('z', [False, False, False, False, False, False, False, False, False, False])

>>> arr2 = zeros(6, 'i')

>>> arr2

array('i', [0, 0, 0, 0, 0, 0])

求素数

`>>> ``nums = range(2, 50) `
`>>> ``for i in range(2, 8): `
`... ``    nums = filter(lambda x: x == i or x % i, nums)`
`... `
`>>> ``print nums`

读取输入:

<pre># Obtain a value from the command line and store it into a variable
>>> import sys
>>> fav_team = sys.stdin.readline()
Cubs
>>> sys.stdout.write("My favorite team is: %s" % fav_team)
My favorite team is: Cubs</pre>

函数

协程:


**def** search_file(filename):
    **print** 'Searching file *%s*' % (filename)
    my_file = open(filename, 'r')
    file_content = my_file.read()
    my_file.close()
    **while** True:
        search_text = (**yield**)
        search_result = file_content.count(search_text)
        **print** 'Number of matches: *%d*' % (search_result)</pre>

Jython脚本编程基础

os.chdir不会改变jvm的启动目录。

>>> import os
>>> os.getcwd()
'/Users/frank/Desktop/frank/hg/jythonbook~jython-book/src/chapter8'
>>> from java.io import File
>>> f = File(".")
>>> for x in f.list():
... print x
...
args.py
search.py
>>> os.chdir("/Users/frank")
>>> os.getcwd()
'/Users/frank'
>>> os.listdir(".")
['Desktop', 'Documents', 'Downloads', 'Dropbox', 'Library', 'Movies', 'Music', 'Pictures', 'Public', 'Sites']
>>> g = File(".")
>>> for x in g.list():
...     print x
...
args.py
search.py

编译代码

!/usr/local/jython2.7.0/bin/jython

from javax.tools import (ForwardingJavaFileManager, ToolProvider, DiagnosticCollector,)
names = ["/home/andrew/code/python/jythonbook/src/chapter8/HelloWorld.java"]
compiler = ToolProvider.getSystemJavaCompiler()
diagnostics = DiagnosticCollector()
manager = compiler.getStandardFileManager(diagnostics, None, None)
units = manager.getJavaFileObjectsFromStrings(names)
comp_task = compiler.getTask(None, manager, diagnostics, None, None, units)
success = comp_task.call()
manager.close()

import os
import sys
import glob

from javax.tools import (forwardingjavafilemanager, toolprovider,

     diagnosticcollector,)

tasks = {}

def task(func):

tasks[func.func_name] = func

@task
def clean():

files = glob.glob("\*.class")
**for** file **in** files:
    os.unlink(file)

@task
def compile():

files = glob.glob("\*.java")
_log("compiling *%s*" % files)
**if** **not** _compile(files):
    quit()
_log("compiled")

def _log(message):

**if** options.verbose:
    **print** message

def _compile(names):

compiler = toolprovider.getsystemjavacompiler()
diagnostics = diagnosticcollector()
manager = compiler.getstandardfilemanager(diagnostics, none, none)
units = manager.getjavafileobjectsfromstrings(names)
comp_task = compiler.gettask(none, manager, diagnostics, none, none, units)
success = comp_task.call()
manager.close()
**return** success

if name == '__main__':

**from** **optparse** **import** optionparser
parser = optionparser()
parser.add_option("-q", "--quiet",
    action="store_false", dest="verbose", default=true,
    help="don't print out task messages.")
parser.add_option("-p", "--projecthelp",
    action="store_true", dest="projecthelp",
    help="print out list of tasks.")
(options, args) = parser.parse_args()

**if** options.projecthelp:
    **for** task **in** tasks:
        **print** task
    sys.exit(0)

**if** len(args) < 1:
    **print** "usage: jython builder.py [options] task"
    sys.exit(1)

**try**:
    current = tasks[args[0]]
**except** KeyError:
    **print** "task *%s* not defined." % args[0]
    sys.exit(1)
current()</pre>

public class HelloWorld {
public static void main(String[] args) {
    System.out.println("Hello, World");
}

}

[frank@pacman chapter8]$ jython builder.py --help
Usage: builder.py [options]

Options:

-h, --help show this help message and exit
-q, --quiet Don't print out task messages.
-p, --projecthelp Print out list of tasks.

[frank@pacman chapter8]$ jython builder.py --projecthelp
compile
clean
[frank@pacman chapter8]$ jython builder.py compile
compiling ['HelloWorld.java']
compiled
[frank@pacman chapter8]$ ls
HelloWorld.java HelloWorld.class builder.py
[frank@pacman chapter8]$ jython builder.py clean
[frank@pacman chapter8]$ ls
HelloWorld.java builder.py
[frank@pacman chapter8]$ jython builder.py --quiet compile
[frank@pacman chapter8]$ ls
HelloWorld.class HelloWorld.java builder.py
[frank@pacman chapter8]$

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
18天前
|
人工智能 安全 Java
Java和Python在企业中的应用情况
Java和Python在企业中的应用情况
45 7
|
24天前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
60 9
|
15天前
|
SQL Java 索引
java小工具util系列2:字符串工具
java小工具util系列2:字符串工具
133 83
|
12天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
28 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
15天前
|
Java 数据库
java小工具util系列1:日期和字符串转换工具
java小工具util系列1:日期和字符串转换工具
50 26
|
16天前
|
Java
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
45 24
|
6天前
|
数据可视化 编译器 Python
Manim:数学可视化的强大工具 | python小知识
Manim(Manim Community Edition)是由3Blue1Brown的Grant Sanderson开发的数学动画引擎,专为数学和科学可视化设计。它结合了Python的灵活性与LaTeX的精确性,支持多领域的内容展示,能生成清晰、精确的数学动画,广泛应用于教育视频制作。安装简单,入门容易,适合教育工作者和编程爱好者使用。
52 7
|
15天前
|
数据采集 存储 监控
Java爬虫:数据采集的强大工具
在数据驱动的时代,Java爬虫技术凭借其强大的功能和灵活性,成为企业获取市场信息、用户行为及竞争情报的关键工具。本文详细介绍了Java爬虫的工作原理、应用场景、构建方法及其重要性,强调了在合法合规的前提下,如何有效利用Java爬虫技术为企业决策提供支持。
|
18天前
|
Java 程序员 开发工具
在比较Java和Python哪个更易学
在比较Java和Python哪个更易学
29 4
|
19天前
|
机器学习/深度学习 人工智能 自然语言处理
比较Python和Java哪个更好
比较Python和Java哪个更好
36 5