微信号:CodePush

介绍:为程序员提供最优质的博文、最精彩的讨论、最实用的开发资源;提供最新最全的编程学习资料:PHP、Objective-C、Java、Swift、C/C++函数库、.NET Framework类库、J2SE API等等.并不定期奉送各种福利.

python与java对接工具Jython介绍

2018-10-12 10:25 程序员大咖


Java编程精选
点击右侧关注,免费入门到精通!


作者丨python人工智能找电子书

https://www.jianshu.com/p/51d64bb620cc


快速入门


下面我们使用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 201502: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 201502: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

[12]


比较老的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', [12345])

>>> 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', [000000])


求素数


`>>> ``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

编译代码
···#!python
#!/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()

<pre>**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>

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

<pre>[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]$</pre>


【点击成为源码大神】

 
程序员大咖 更多文章 在Facebook面试了200位程序员,教你40招搞定大厂算法面试 假期领导微信发需求,程序员:很讨厌现在的状态,回来准备辞职了 年薪30万却因没房被女方家庭嫌弃,程序员:我们可以一起奋斗啊 IT公司老板落水,各部门员工怎么救 重磅!编程进入重庆中小学,连课时都定了
猜您喜欢 创建和销毁对象 熊市深度记录 4 | 筑底的过程 Nginx/LVS/HAProxy负载均衡软件的优缺点详解 Android Bitmap缓存池使用详解 震惊世界的斯坦福死亡实验:我们释放了你心底的恶魔!深思极恐!