快速入门
下面我们使用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
读取输入:
# 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
函数
协程:
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)
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()
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]$