(Python编程)Jython:Java的Python

Programming Python, 3rd Edition 翻译
最新版本见wiki: http://wiki.woodpecker.org.cn/moin/PP3eD
欢迎参与翻译与修订。

18.4. Jython: Python for Java

18.4. Jython:Java的Python

Jython (formerly known as JPython) is an entirely distinct implementation of the Python programming language that allows programmers to use Python as an easy-to-use scripting component in Java-based applications. The effect is much the same as deploying standard Python as a scripting language for C and C++ libraries.

Jython(以前叫JPython)是Python编程语言一个完全独特的实现,它让程序员能够在基于Java的应用中使用Python,使Python成为一个易用的脚本部件。其效果如同部署标准Python作为C和C++库的脚本语言。

In short, Jython makes Python code look like Java and consequently offers a variety of technology options inherited from the Java world. With Jython, Python code may be run as client-side applets in web browsers, as server-side scripts, and in a variety of other roles. Jython is distinct from other systems mentioned in this section in terms of its scope: while it is based on the core Python language we've seen in this book, it actually replaces the underlying implementation of that language rather than augmenting it.[*]

简单地说,Jython使Python代码看起来像Java代码,因此可以使用各种源自Java世界的技术。利用Jython,Python代码可以作为客户端applet运行于网页浏览器,也可以用作服务器端的脚本,以及用于其它多种场合。Jython在范畴上不同于本章所述的其它系统:它虽然基于核心的Python言语,但它实际上是替换了Python语言的底层实现而不是扩展它。[*]

[*] Jython was the second complete implementation of the Python language. By contrast, the standard, original implementation of Python is sometimes now referred to as CPython, because it is implemented in ANSI C. Among other things, the Jython implementation is driving a clearer definition of the Python language itself, independent of a particular implementation's effects. The newer IronPython Python implementation for Microsoft's C#/.NET environment (mentioned later in this chapter in the sidebar "The IronPython C# Python Compiler") is a third Python implementation, and like Jython, it is also helping to form a definition of what it means to be Python.

[*] Jython是Python语言的第二个完整实现。原来标准的Python现在有时被称为CPython,因为它是ANSI C的实现。除了别的以外,Jython实现自身具有对Python语言的更清晰的定义,不受其它特定实现的影响。微软的C#/.NET环境下新的 Python实现IronPython(将在本章后面的边栏“IronPython C# Python编译器”中提及),是第三个Python实现,与Jython一样,也是形成了自己对Python的定义。

This section briefly explores Jython and highlights some of the reasons you may or may not want to use it instead of the standard Python implementation. Although Jython is primarily of interest to programmers writing Java-based applications, it underscores integration possibilities and language definition issues that merit the attention of Python users. Because Jython is Java-centric, you need to know something about Java development to make the most sense of Jython, and this book doesn't pretend to teach that in the next few pages. For more details, interested readers should consult other materials, including Jython documentation at http://www.jython.org.

本节将概要地浏览Jython,并突出用Jython替换标准Python的一些原因,以及不应该替换的原因。尽管Jython主要用于编写基于Java 的应用,但它强调了集成的可能性和语言定义问题,值得Python用户关注。因为Jython是以Java为中心的,你需要了解一些Java才能搞清楚 Jython,而老实说,本书下面几页并不能教会你Java和Jython。有兴趣的读者应该阅读其它资料以获取更多内容,其中包括Jython文档 http://www.jython.org。

The Java version of Python is now called Jython. Although you are likely to still see it called by its new Jython name on the Net these days (and in this book), its original "JPython" title may still appear in older documentation (it was renamed some years ago for copyright reasons).

Java版的Python现在被称为Jython。现在你在网上或本书中看到,它被称呼为新的名字Jython,但它的原名"JPython"可能仍会在旧文档中出现(它因为版权原因在几年前才重命名)。


18.4.1. A Quick Introduction to Jython

18.4.1. Jython简介

Functionally speaking, Jython is a collection of Java classes that run Python code. It consists of a Python compiler, written in Java, that translates Python scripts to Java bytecode so they can be executed by a Java Virtual Machinethe runtime component that executes Java programs and is used by major web browsers. Moreover, Jython automatically exposes all Java class libraries for use in Python scripts. In a nutshell, here's what comes with the Jython system:

从功能上说,Jython是一些可以运行Python代码的Java类。它包含一个Python编译器,是用Java写的,它能将Python脚本翻译成 Java字节码,使之能运行于Java虚拟机,即大部份浏览器所使用的能运行Java程序的虚拟机。另外,Jython自动导出了所有Java类库,使之能用于Python脚本。概括起来,以下就是Jython系统所提供的:


Python-to-Java-bytecode compiler

Python到Java字节码的编译器

Jython always compiles Python source code into Java bytecode and passes it to a Java Virtual Machine (JVM) runtime engine to be executed. A command-line compiler program, jythonc, is also able to translate Python source code files into Java .class and .jar files, which can then be used as Java applets, beans, servlets, and so on. To the JVM, Python code run through Jython looks the same as Java code. Besides making Python code work on a JVM, Jython code also inherits all aspects of the Java runtime system, including Java's garbage collection and security models. jythonc imposes Java source file class rules as well.

Jython总是将Pytnon源代码编译成Java字节码,并传给Java虚拟机(VJM)运行引擎执行。有一个命令行编译程序jythonc,能将 Python源文件转化为Java .class.jar文件,使之成为Java applet, beans, servlet, 等等。对JVM来说,通过Jython运行的Python代码看上去与Java代码是一样的。除了让Python代码运行于JVM,Jython代码同时继承了所有Java运行时系统的特征,包括Java的垃圾回收和安全模型。jythonc也适用Java源文件类规则。


Access to Java class libraries (extending)

操作Java类库(扩展)

Jython uses Java's reflection API (runtime type information) to expose all available Java class libraries to Python scripts. That is, Python programs written for the Jython system can call out to any resident Java class automatically, simply by importing it. The Python-to-Java interface is completely automatic and remarkably seamlessJava class libraries appear as though they are coded in Python. Import statements in Jython scripts may refer to either Jython modules or Java class libraries. For instance, when a Jython script imports java.awt, it gains access to all the tools available in the awt library. Jython internally creates a "dummy" Python module object to serve as an interface to awt at import time. This dummy module consists of hooks for dispatching calls from Jython code to Java class methods and automatically converting datatypes between Java and Python representations as needed. To Jython scripts, Java class libraries look and feel exactly like normal Python modules (albeit with interfaces defined by the Java world).

Jython利用Java的反射API(运行时类型信息),将所有可用的Java类库导出到Python脚本。就是说,为Jython系统写的 Python程序可以调用任何Java类,只需导入。Python到Java的接口是完全自动化,天衣无缝的。Java类库像是用Python编码的。导入语句既可以指向Jython模块,也可以是Java类库。例如,当一个Jython脚本导入java.awt后, 它就能使用awt库中的所有工具。导入时,Jython内部创建了一个“假”Python模块对象作为awt的接口。这个假模块能够分派Jython代码对Java类方法的调用,并自动在Java与Python之间转换数据类型。对Jython脚本来说,Java类库完全像是正常的Python模块(虽然接口是由Java定义的)。


Unified object model

统一对象模型

Jython objects are actually Java objects internally. In fact, Jython implements Python types as instances of a Java PyObject class. For instance, in Jython, the number 123 is an instance of the PyInteger Java class, and you can specify things like []._ _class_ _, since all objects are class instances (this works in standard C Python today as well). That makes data mapping between languages simple. Java can process Python objects automatically, because they are Java objects. Jython automatically converts types between languages according to a standard type map as needed to call out to Java libraries, and it selects among overloaded Java method signatures.

Jython对象内部实际上是Java对象。事实上,Jython把Python类型实现为Java类PyObject的实例。例如,在Jython中,数字123是Java类PyInteger的实例,你可以像[]._ _class_ _这样来确定东西,因为所有对象都是类实例(这也能用于目前的标准Python)。那使语言之间的数据映射变得简单。Java能自动处理Python对象,因为它们是Java对象。当Jython调用进入Java库时,如果有需要,它通过一个标准的类型映射自动在语言间转换类型,并且能够在重载的 Java方法签名中进行选择。


API for running Python from Java (embedding)

在Java中运行Python的API接口(内嵌)

Jython also provides interfaces that allow Java programs to execute Jython code. As for embedding in C and C++, this allows Java applications to be customized by bits of dynamically written Jython code. For instance, Jython ships with a Java PythonInterpreter class, which allows Java programs to create objects that function as Python namespaces for running Python code. Each PythonInterpreter object is roughly a Python module, with methods such as exec (a string of Python code), execfile (a Python filename), and get and set methods for assigning Python global variables. Because Python objects are really instances of a Java PyObject class, an enclosing Java layer can access and process data created by Python code naturally.

Jython也提供了接口,允许Java程序执行Jython代码。就像在C和C++中内嵌一样,它允许Java应用通过动态编写的Jython代码进行定制。例如,Jython有一个Java类PythonInterpreter,它允许Java程序创建Python命名空间来运行Python代码。每个PythonInterpreter对象大体上是一个Python模块,具有诸如下列的函数:exec(Python代码字符串),execfile(Python文件),并且具有存取Python全局变量的getset函数。因为Python对象就是Java类PyObject的实例,Java外壳层能够自然地操作与处理Python代码所创建的数据。


Interactive Python command line

交互式Python命令行

Like the standard Python implementation, Jython comes with an interactive command line that runs code immediately after it is typed. Jython's jython program is equivalent to the python executable we've been using in this book; without arguments, it starts an interactive session. Among other things, this allows Jython programmers to import and test class components actually written in Java. This ability alone is compelling enough to interest many Java programmers.

就像标准的Python实现,Jython具有一个交互式命令行,可以敲入代码立即运行。Jython的jython程序等同于本书中一直使用的python执行程序;不带参数运行,它将启动一个交互式会话。除了其它功能,它允许Jython程序员们导入和测试实际上是用Java写的类部件。仅这一功能就足以吸引许多Java程序员。


Interface automations

接口自动化

Java libraries are somewhat easier to use in Jython code than in Java. That's because Jython automates some of the coding steps Java implies. For instance, callback handlers for Java GUI libraries may be simple Python functions even though Java coders need to provide methods in fully specified classes (Java does not have first-class function objects). Jython also makes Java class data members accessible as both Python attribute names (object.name) and object constructor keyword arguments (name=value); such Python syntax is translated into calls to getName and setName accessor methods in Java classes. We'll see these automation tricks in action in the following examples. You don't have to use any of these (and they may confuse Java programmers at first glance), but they further simplify coding in Jython and give Java class libraries a more Python-like flavor.

Java库在Jython代码中的使用比在Java中稍微简单点。那是因为Jython自动处理了Java所隐含的一些编码过程。例如,Java GUI库的回调处理器可以是简单的Python函数,而Java编码人员需要在接口完全限定的类中提供方法(Java没有第一类的函数对象)。 Jython使Java类数据成员的存取既可以通过Python属性名(object.name),也可以通过对象构造器关键字参数(name=value);这种Python语法会转换成Java类的getNamesetName存取函数的调用。在下面的例子中,我们会看到这些自动化窍门的实际运用。你并非必须使用这些窍门(Java程序员初次用这些技巧可能会搞糊涂),但是它们进一步简化了Jython编码,并使 Java类库更具Python的风味。

The net effect of all this is that Jython allows us to write Python programs that can run on any Java-aware machinein particular, in the context of most web browsers. More important, because Python programs are translated into Java bytecode, Jython provides an incredibly seamless and natural integration between the two languages. Both walk and talk in terms of the Java model, so calls across language boundaries are trivial. With Jython's approach, it's even possible to subclass a Java class in Python, and vice versa.

所有这些的实际效果是,Jython让我们写的Python程序可以运行在任何兼容Java的机器上,特别的,如大多数浏览器环境。更重要的,因为 Python程序能转化为Java字节码,Jython在两种语言之间不可置信地提供了一种无缝自然的集成。Jython以Java的模式走路与说话,因此跨语言边界调用变得简单。通过Jython,甚至可以在Python中继承Java类,或反过来。

18.4.2. Why Jython?

18.4.2. 为什么要Jython?

So why go to all this trouble to mix Python into Java environments? The most obvious answer is that Jython makes Java components easier to use: Jython scripts are typically a fraction of the size of their Java equivalents, and are much less complex. More generally, the answer is really the same as it is for C and C++ environments. Python, as an easy-to-use, object-oriented scripting language, naturally complements the Java programming language.

但是为什么要费劲地将Python掺入到Java环境中去呢?最明显的原因是Jython使Java部件更容易使用:Jython脚本比相同功能的 Java代码要简短的多,也没有那么复杂。而更一般的原因与C和C++环境下要集成Python的原因一致。Python作为一种简单易用,面向对象的脚本语言,很自然地补充了Java语言的不足。

By now, it is clear to most people that Java is too complex to serve as a scripting or rapid-development tool. But this is exactly where Python excels; by adding Python to the mix with Jython, we add a scripting component to Java systems, exactly as we do when integrating Python with C or C++. For instance, we can use Jython to quickly prototype Java systems, test Java classes interactively, and open up Java systems for end-user customization. In general, adding Python to Java development can significantly boost programmer productivity, just as it does for C and C++ systems.

到如今,大多数人都清楚,Java太复杂,不能用作脚本,或是快速开发工具。而这正是Python胜出的地方;Jython通过集成Python,给 Java系统添加了一个脚本部件,就像C/C++中集成Python一样。例如,我们可以用Jython快速创建Java系统的原型,交互式测试Java 类,或开放Java系统供用户定制。一般而言,Java加入Python可以显著地提高程序员的生产力,就像Python对C和C++系统的作用一样。

Jython Versus the Python C API

Jython与Python C API对比

Functionally, Jython is primarily an integration system: it allows us to mix Python with Java components. We also study ways to integrate Python with C and C++ components in a later part of this book. It's worth noting that we need different techniques to integrate Python with Java (such as the Jython compiler), because Java is a somewhat closed system: it prefers an all-Java mix. The C and C++ integration tools are generally less restrictive in terms of language assumptions, and any C-compatible language components will do. Java's strictness is partly due to its security goals, but the net effect is to foster integration techniques that are specific to Java alone.

功能上,Jython主要是一个集成系统:它允放我们混合Python和Java部件。本书后面我们还会研究Python集成C和C++部件的方法。值得注意的是,我们需要不同的技术来集成Python和Java(譬如Jython编译器),因为Java是一个有点封闭的系统:它更喜欢全Java的混合。 C和C++的集成工具在语言的假定上通常不太有限制性,可以使用任何C兼容的语言部件。Java的严格性在一定程度上缘于它的安全性目标,而结果就造成了 Java特有的集成技术。

On the other hand, because Java exposes runtime type information through its reflection API, Jython can largely automate the conversions and dispatching needed to access Java components from Python scripts; Python code simply imports and calls Java components. When mixing Python with C or C++, we must provide a "glue" code layer that integrates the two languages explicitly. Some of this can be automated (with the SWIG system we'll meet later in this text). No glue code is required in Jython, however, because Jython's (and Java's) developers have done all the linkage work already, in a generic fashion. It is also possible to mix in C/C++ components with Java via its native call interface (JNI), but this can be cumbersome and may cancel out Java's reported portability and security benefits.

另一方面,因为Java通过反射API暴露运行时类型信息,Jython可以在很大程度上自动化处理,从Python脚本操作Java部件时的转换与分派工作:Python代码只需简单地导入并调用Java部件。当混合Python与C或C++时,我们必须明确地提供一个“粘合”代码层来融合两种语言。其中部份工作可以自动化(如使用本书后面所述的SWIG系统)。而Jython不需要粘合代码,因为Jython(和Java)开发者已经以一种通用的方式,完成了链接工作。通过Java的本地调用接口(JNI),Java也是有可能混合C/C++部件的,但是这很麻烦,而且会消除Java所报导的可移植性和安全性。


18.4.3. A Simple Jython Example

18.4.3. 一个Jython简例

Once a Python program is compiled with Jython, it is all Java: the program is translated to Java bytecode, it uses Java classes to do its work, and there is no Python left except for the original source code. Because the compiler tool itself is also written in Java, Jython is sometimes called "100 percent pure Java." That label may be more profound to marketers than programmers, though, because Jython scripts are still written using standard Python syntax, use Python datatypes, and import many of Python's standard library modules. For instance, Example 18-5 is a legal Jython program, derived from an example originally written by Guido van Rossum.

Python程序用Jython编译后,它就是Java的了:它已经转化为Java字节码,虽然源码是Python的,但它运行的是Java类,与Python已经无关了。因为编译器本身是用Java编写的,Jython有时被称为“百分之百的纯Java”。当然这一称法只是对市场人员有意义,对于程序员来说,Jython脚本仍是按标准的Python语法编写的,使用Python数据类型,并且导入了许多Python标准库模块。例如,例18-5改编自Guido van Rossum的原作,它是一个合法的Jython程序。

Example 18-5. PP3E/Internet/Other/Jython/jycalc.py

# ########################################################################
#
 implement a simple calculator in Jython; evaluation runs a full
#
 expression all at once using the Python eval( ) built-in--Jython's
#
 source-code compiler is present at runtime, as in standard Python
#
########################################################################

from  java  import  awt                    #  get access to Java class libraries
from  pawt  import  swing                  #  they look like Python modules here

labels 
=  [ ' 0 ' ' 1 ' ' 2 ' ' + ' ,           #  labels for calculator buttons
           ' 3 ' ' 4 ' ' 5 ' ' - ' ,           #  will be used for a 4x4 grid
           ' 6 ' ' 7 ' ' 8 ' ' * ' ,
          
' 9 ' ' . ' ' = ' ' / '  ]

keys 
=  swing.JPanel(awt.GridLayout( 4 4 ))       #  do Java class library magic
display  =  swing.JTextField( )                   #  Python data auto-mapped to Java

def  push(event):                                 #  callback for regular keys
    display.replaceSelection(event.actionCommand)

def  enter(event):                              #  callback for the '=' key
    display.text  =  str(eval(display.text))     #  use Python eval( ) to run expr
    display.selectAll( )

for  label  in  labels:                           #  build up button widget grid
    key  =  swing.JButton(label)                 #  on press, invoke Python funcs
     if  label  ==   ' = ' :
        key.actionPerformed 
=  enter
    
else :
        key.actionPerformed 
=  push
    keys.add(key)

panel 
=  swing.JPanel(awt.BorderLayout( ))       #  make a swing panel
panel.add( " North " , display)                      #  text plus key grid in middle
panel.add( " Center " , keys)
swing.test(panel)                               
#  start in a GUI viewer

 

The first thing you should notice is that this is genuine Python codeJython scripts use the same core language that we've been using all along in this book. That's good news, both because Python is such an easy language to use and because you don't need to learn a new, proprietary scripting language to use Jython. It also means that all of Python's high-level language syntax and tools are available. For example, in this script, the Python eval built-in function is used to parse and evaluate constructed expressions all at once, saving us from having to write an expression evaluator from scratch.

首先请注意,这是纯正的Python代码: Jython脚本与本书一直在用的语言核心是相同的。这是好事,既因为Python是如此简单,也因为你不必再去学习一门新的,私有的语言。这也意味着可以使用Python所有的高级语法与工具。例如,在这个脚本中,使用了Python内建函数eval,分析与计算表达式同时完成,我们就不必从零开始写表达式计算器了。

18.4.4. Interface Automation Tricks

18.4.4. 接口自动化的窍门

The previous calculator example also illustrates two interface automations performed by Jython: function callback and attribute mappings. Java programmers may have already noticed that this example doesn't use classes. Like standard Python and unlike Java, Jython supports but does not impose object-oriented programming (OOP). Simple Python functions work fine as callback handlers. In Example 18-5, assigning key.actionPerformed to a Python function object has the same effect as registering an instance of a class that defines a callback handler method:

上面的计算器也同时示例了Jython所做的两个接口自动化:函数回调与属性映射。Java程序员可能已经注意到这个例子并没有使用类。不像Java而更像标准Python,Jython支持但不强制面向对象编程(OOP)。简单的Python函数就可以作为回调处理器。在例18-5中,key.actionPerformed赋值为一个Python函数对象,效果就像注册一个具有回调处理函数的类:

def  push(event):
    ...
key 
=  swing.JButton(label)
key.actionPerformed 
=  push

This is noticeably simpler than the more Java-like:

这比Java的方式简单的多:

class  handler(awt.event.ActionListener):
    def actionPerformed(self, event):
        ...
key 
=  swing.JButton(label)
key.addActionListener(handler( ))

Jython automatically maps Python functions to the Java class method callback model. Java programmers may now be wondering why we can assign to something named key.actionPerformed in the first place. Jython's second magic feat is to make Java data members look like simple object attributes in Python code. In abstract terms, Jython code of the form:

Jython自动将Python函数映射为Java的回调类。Java程序员现在可能还会问,为什么能直接赋值给key.actionPerformed?Jython的另一神功是让Java的数据成员看起来像Python代码中简单的对象属性。简单来说就是,以下 Jython代码:

 
=  Object(argument)
X.property 
=  value  +  X.property

is equivalent to the more traditional and complex Java style:

等效于传统的Java风格的复杂代码:

=  Object(argument)
X.setProperty(value 
+  X.getProperty( ))

That is, Jython automatically maps attribute assignments and references to Java accessor method calls by inspecting Java class signatures (and possibly Java BeanInfo files if used). Moreover, properties can be assigned with keyword arguments in object constructor calls, such that:

也就是说,Jython自动将属性赋值与引用映射为Java的存取函数,这是通过检查Java类签名实现的(如果存在,也会检查Java BeanInfo文件)。而且,属性可以在对象构造函数调用时,使用关键字参数进行赋值,如:

=  Object(argument, property = value)
 

is equivalent to both this more traditional form:

等效于传统形式:

=  Object(argument)
X.setProperty(value)
 

as well as the following, which relies on attribute name mapping:

也可以利用属性名映射,采用如下方式:

=  Object(argument)
X.property 
=  value
 

We can combine both callback and property automation for an even simpler version of the callback code snippet:

组合应用回调与属性自动化,可以生成下面这样的更简单的回调代码:

def  push(event):
    ...
key 
=  swing.JButton(label, actionPerformed = push)
 

You don't need to use these automation tricks, but again, they make Jython scripts simpler, which is most of the point behind mixing Python with Java.

你不必非得使用这些自动化的窍门,但是这些窍门简化了Jython脚本,而简化是混合Python与Java的主旨。

18.4.5. Writing Java Applets in Jython

18.4.5. 用Jython写Java Applet

I would be remiss if I didn't include a brief example of Jython code that more directly masquerades as a Java applet: code that lives on a server machine but is downloaded to and run on the client machine when its Internet address is referenced. Most of the magic behind this is subclassing the appropriate Java class in a Jython script, demonstrated in Example 18-6.

如果我不包含一个Jython代码作为Java applet的简例,那将是我的疏忽。Java applet是放在服务器上的代码,能通过指定网址下载到客户端并运行。Jython代码能够直接地伪装成Java applet。其背后主要的玄机在于Jython脚本类继承了Java Applets类,见例18-6。

Example 18-6. PP3E/Internet/Other/Jython/jyapplet.py

# ######################################
#
 a simple Java applet coded in Python
#
######################################

from  java.applet  import  Applet                             #  get Java superclass

class  Hello(Applet):
    
def  paint(self, gc):                                   #  on paint callback
        gc.drawString( " Hello applet world " 20 30 )        #  draw text message

if  _ _name_ _  ==   ' _ _main_ _ ' :                                #  if run standalone
     import  pawt                                            #  get Java awt lib
    pawt.test(Hello( ))                                         #  run under awt loop

 

The Python class in this code inherits all the necessary applet protocol from the standard Java Applet superclass, so there is not much new to see here. Under Jython, Python classes can always subclass Java classes, because Python objects really are Java objects when compiled and run. The Python-coded paint method in this script will be automatically run from the Java AWT event loop as needed; it simply uses the passed-in gc user-interface handle object to draw a text message.

这段代码中的Python类从标准Java Applet父类中继承了所有必需的applet协议,所以这里并没有什么新东西。在Jython下,Python类总是能继承Java类,因为 Python对象编译完并运行时,实际上就是Java对象。这段脚本中Python编码的paint方法将会在Java AWT事件循环中自动运行,它简单地使用传入的用户界面句柄对象gc来绘制一条文本信息。

If we use Jython's jythonc command-line tool to compile this into a Java .class file and properly store that file on a web server, it can then be used exactly like applets written in Java. Because most web browsers include a JVM, this means that such Python scripts may be used as client-side programs that create sophisticated user-interface devices within the browser, and so on.

如果我们用Jython的命令行工具jythonc来将这段代码编译成Java .class文件,并放在web服务器合适的地方,它就可以像Java写的applet一样使用。因为大多数网页浏览器包含一个JVM,这就意味着这样的 Python脚本可以用作客户端程序,可以在浏览器中创建复杂的用户界面,等等。

18.4.6. Jython Trade-Offs

18.4.6. Jython的权衡

Depending on your background, the potentially less good news about Jython is that even though the calculator and applet scripts discussed here are straight Python code, the libraries they use are different from what we've seen so far. In fact, the library calls employed are radically different. The calculator, for example, relies primarily on imported Java class libraries, not on standard Python libraries. You need to understand Java's awt and swing libraries to make sense of its code, and this library skew between language implementations becomes more acute as programs grow larger. The applet example is even more Java bound: it depends both on Java user-interface libraries and on Java applet protocols.

与你的知识背景有关,不好的消息是,尽管此处讨论的计算器与applet的脚本是简单的Python代码,但它们所使用的库与我们以前所见的有所不同。实际上,所调用的库是根本不同的。例如计算器,主要是导入Java类库,而并非标准的Python库。你需要理解Java的awtswing库才能读懂这个代码,当程序增大时,这种不同语言实现之间的库差异将变得很严重。applet的例子则更是Java化的:它不仅依赖于Java用户界面库,同时依赖于 Java的applet协议。

If you are already familiar with Java libraries, this isn't an issue at all, of course. But because most of the work performed by realistic programs is done by using libraries, the fact that most Jython code relies on very different libraries makes compatibility with standard Python less potent than it may seem at first glance. To put that more strongly, apart from simple core language examples, many Jython programs won't run on the standard Python interpreter, and many standard Python programs won't work under Jython.

当然,如果你已经熟悉Java库,这就完全不成问题。但是,因为现实中程序所做的大部份工作是通过库的使用完成的,多数Jython代码依赖于很不相同的库,这一事实使得最初认为的与标准Python的兼容性变得不那么有效。更彻底点说,除了一些简单的核心语言的例子,许多Jython程序不会运行于标准的Python解释器上,而许多标准的Python程序也不会工作在Jython下。

Generally, Jython presents a number of trade-offs. I want to point out upfront that Jython is indeed an excellent Java scripting toolarguably the best one available, and most of its trade-offs are probably of little or no concern to Java developers. For instance, if you are coming to Jython from the Java world, the fact that Java libraries are at the heart of Jython scripts may be more asset than downside. But if you are presented with a choice between the standard and Java-based Python language implementations, some of Jython's implications are worth knowing about:

一般说来,Jython体现了某些权衡。首先我要指出,Jython真的是一种卓越的Java脚本工具,可能是现有最好的,其最大的权衡可能是,没有或很少关心到Java开发者。例如,如果你是Java阵营的,Jython脚本以Java库为中心这一事实,对你来说可能更多的是有利而不是不利。但是,如果你面对标准Python与基于Java的Python语言实现的选择时,你必须知道一些Jython的暗意:

(译注:应该是对Python关心太少吧?Jython好像是为Java开发者服务的。)


Jython is not fully compatible with the standard Python language

Jython与标准Python语言并非完全兼容

At this writing, Jython is not yet totally compatible with the standard Python language, as defined by the original C implementation. In subtle ways, the core Python language itself works differently in Jython. The list of incompatibilities (viewable at http://www.jython.org) will likely shrink over time but will probably never go away completely. Moreover, new language features are likely to show up later in Jython than in the standard C-based implementation.

本书所作时,Jython还不是完全兼容标准Python语言,标准是由原C语言实现定义的。核心Python语言本身与Jython有细微的不同。不兼容性列表(见http://www.jython.org)可能会随着时间缩小,但是不太可能完全消失。而且,新的语言特性可能出现在Jython,而没有在标准的基于C语言的实现中出现。


Jython requires programmers to learn Java development too

Jython要求程序员也要学习Java开发

Language syntax is only one aspect of programming. The library skew mentioned previously is just one example of Jython's dependence on the Java system. Not only do you need to learn Java libraries to get real work done in Jython, but you also must come to grips with the Java programming environment in general.

语法仅是编程的一方面。前面所提的库交叉只是Jython依赖于Java系统的一个例子。为了能用Jython完成实际工作,你不仅需要学习Java库,你还必须掌握通常的Java编程环境。

Most standard Python libraries have been ported to Jython, and others are being adopted regularly. But major Python tools such as Tkinter GUIs may show up late or never in Jython (and instead are replaced with Java tools).[*] In addition, many core Python library features cannot be supported in Jython, because they would violate Java's security constraints. For example, some tools in the os module may never become available in Jython.

大多数标准Python库已经移植到Jython,并且其它的库也正在定期地被采纳。但是主要的Python工具,例如Tkinter GUI,可能要晚点才出来,也可能永远不会在Jython中出现(并被Java工具所替代)。[*] 还有,Jython不支持核心Python库中的许多特性,因为它们违反Java的安全性约束。例如,Jytnon不能使用os模块中的一些工具。

[*] But see the note at the end of the later section "Grail: A Python-Based Web Browser"; a port of Tkinter for Jython known a jTkinter is available. Search the Web for details.

[*] 但是有一个Tkinter的移植jTkinter,见下面“Grail: 基于Python的网页浏览器”一节结尾处的注释。详情请搜索网络。


Jython applies only where a JVM is installed or shipped

Jython要求JVM的分发与安装

You need the Java runtime to run Jython code. This may sound like a nonissue given the pervasiveness of the Internet, but I have worked in more than one company for which delivering applications to be run on JVMs was not an option. Simply put, there was no JVM to be found at the customer's site. In such scenarios, Jython is either not an option, or it will require you to ship a JVM with your application just to run your compiled Jython code.

你需要Java运行库才能运行Jython代码。由于因特网的普遍性,这可能不成问题,但是我工作过的公司中,不止一家,交付的应用程序运行于无法安装 JVM的环境。最简单的,如客户机没有JVM。这种情况下,要么不选Jython,要么需要与应用程序同时分发JVM,这样才能运行你编译的Jython 代码。

Shipping the standard Python system with your products is completely free; shipping a JVM may imply licensing and fee issues (though open source options do now exist). On some platforms, finding a JVM to use for development might be an issue as well; see http://www.jython.org for current JVM compatibility issues.

你的产品附带分发标准Python系统是完全免费的;分发JVM可能有许可和费用问题(尽管现在有开源的选择)。在有些平台上,寻找一个开发用的JVM,可能也是个问题;上http://www.jython.org查看当前的JVM兼容问题。


Jython doesn't support Python extension modules written in C or C++

Jython不支持C或C++写的Python扩展模块

At present, no C or C++ extension modules written to work with the C Python implementation will work with Jython. This is a major impediment to deploying Jython outside the scope of applications run in a browser. To date, the Python user community has developed thousands of extensions written for C Python, and these constitute much of the substance of the Python development world.

目前,为C Python而写的C或C++模块没有一个能工作于Jython。这是部署Jython的主要障碍,浏览器应用除外。到目前为止,Python用户群已经开发了成千上万的为C Python而写的扩展,并且以此形成了Python开发世界的大量物质。

Jython's current alternative is to instead expose Java class libraries and ask programmers to write new extensions in Java. But this dismisses a vast library of prior and future Python art. In principle, C extensions could be supported by Java's native call interface, but it is complex and can negate Java portability and security.

Jython的当前的方法是让程序员们用Java重写扩展,并输出Java类库。但这样就抛弃了大量历史的和将来的Python库。原则上,C扩展可以被Java的本地调用接口所支持,但它是复杂的并且会降低Java的可移植性与安全性。


Jython is noticeably slower than C Python

Jython明显的比C Python慢

Today, Python code generally runs slower under the Jython implementation. How much slower depends on what you test, which JVM you use to run your test, whether a Just-in-Time (JIT) compiler is available, and which tester you cite. Posted benchmarks have run the gamut from 1.7 times slower than C Python, to 10 times slower, and up to 100 times slower. Regardless of the exact number, the extra layer of logic Jython requires to map Python to the Java execution model adds speed overheads to an already slow JVM and makes it unlikely that Jython will ever be as fast as the C Python implementation.

目前,Python代码在Jython下运行一般比较慢。慢多少取决于测试的内容,运行的JVM,是否有即时编译器(JIT),以及所使用的测试器。发布的基准数据显示,它比C Python慢1.7到10倍,最高可达100倍。不管具体的数字,为了将Python映射为Java执行模型,需要额外的Jython逻辑层,这增加了速度上的开销,而且JVM本身就慢,所以Jython不太可能像C Python那么快。

Given that C Python is already slower than compiled languages such as C, the additional slowness of Jython makes it less useful outside the realm of Java scripting. Furthermore, the Swing GUI library used by Jython scripts is powerful, but generally is considered to be the slowest and largest of all Python GUI options. Given that Python's Tkinter library is a portable and standard GUI solution, Java's proprietary user-interface tools by themselves are probably not reason enough to use the Jython implementation.

C Python已经比编译性语言如C语言要慢,Jython所附加的慢速使它只能用于Java脚本领域。另外,Jython脚本所用的Swing GUI库虽然很强大,但普遍认为,它是所有Python可选GUI中最大型最慢的。虽然Python的Tkinter库是一个可移植和标准的GUI解决方案,但Java自有一套用户界面工具,可能没有足够理由要去使用Jython实现的Tkinter。


Jython is less robust than C Python

Jython不如C Python健壮

Jython is generally considered to be buggier than the standard C implementation of the language. This is certainly due to its younger age and smaller user base, and it varies from JVM to JVM, but you are more likely to hit snags in Jython. In contrast, C Python has been amazingly bug-free since its introduction in 1990.

一般认为,Jython比标准的C Python实现具有更多的错误。当然是因为它出现时间不长,用户群小,以及随不同JVM而不同,但是使用Jython更有可能碰钉子。另一方面,C Python自从1990年出现以来,早已令人惊异地鲜有错误。


Jython may be less portable than C Python

Jython移植性可能不如C Pytnon

It's also worth noting that the core Python language is far more portable than Java (despite marketing statements to the contrary). Because of that, deploying standard Python code with the Java-based Jython implementation may actually lessen its portability. Naturally, this depends on the set of extensions you use, but standard Python runs today on everything from handheld PDAs, iPods, and cell phones to PCs, Cray supercomputers, and IBM mainframes.

同时值得注意的是,Python语言的核心远比Java移植性强(尽管市场报告是相反的)。因此,使用基于Java的Jython实现来部署标准的 Python代码,可能会降低它的移植性。自然的,这取决于你所使用的扩展库,但是标准的Python目前可运行于以下所有设备,从手持PDA, iPod,手机,到PC,Cray超级计算机,和IBM大型机。

Some incompatibilities between Jython and standard Python can be very subtle. For instance, Jython inherits all of the Java runtime engine's behavior, including Java security constraints and garbage collection. Java garbage collection is not based on standard Python's reference count scheme, and therefore can automatically collect cyclic objects.[*] It also means that some common Python programming idioms won't work. For example, it's typical in Python to code file-processing loops in this form:

Jython与标准Python之间的一些不兼容可能是非常细微的。例如,Jythone继承了所有Java运行时引擎的行为,包括Java安全性约束和垃圾回收。Java垃圾回收并非建立于标准Python的引用计数机制,因此可以自动回收循环对象。[*] 这也意味着一些通用的Python编程惯用法不能用了。例如,这是一个典型的Python代码,循环处理文件:

[*] But as of Python 2.0, its garbage collector can now collect cyclic objects too. See the 2.0 release notes and the gc standard library module in Python's library manual.

[*]但是从Python 2.0起,它的垃圾回收现在也能回收循环对象了。见Python库手册中的2.0发布说明及标准库模块gc。

for  filename  in  bigfilenamelist:
    text 
=  open(filename).read( )
    dostuffwith(text)
 

That works because files are automatically closed when garbage collected in standard Python, and we can be sure that the file object returned by the open call will be immediately garbage collected (it's temporary, so there are no more references as soon as we call read). This won't work in Jython, though, because we can't be sure when the temporary file object will be reclaimed. To avoid running out of file descriptors, we usually need to code this differently for Jython:

能那样做是因为在标准Python中垃圾回收时,文件会自动关闭,我们可以确信,open调用返回的文件对象会立即被垃圾回收(它是临时对象,一旦调用read,它就再也没有被引用了)。然而这不能用于Jython,因为我们不能确信何时临时文件对象才能收回。为了避免用光文件描述符,Jython通常需要这样编码:

for  filename  in  bigfilenamelist:
    file 
=  open(filename)
    text 
=  file.read( )
    dostuffwith(text)
    file.close( )
 

You may face a similar implementation mismatch if you assume that output files are immediately closed: open(name,'w').write(bytes) collects and closes the temporary file object and hence flushes the bytes out to the file under the standard C implementation of Python only, and Jython instead collects the file object at some arbitrary time in the future.

如果你假定输出文件会被立即关闭,你可能面临类似的实现上的差异:仅在Python标准的C实现中,open(name,'w').write(bytes)会回收和关闭临时文件对象,因此清空缓冲区数据保存到文件,而Jython是在未来不确定的时刻回收文件对象。

18.4.7. Picking Your Python

18.4.7. 选择你的Python

Because of concerns such as those just mentioned, the Jython implementation of the Python language is probably best used only in contexts where Java integration or web-browser interoperability is an important design goal. You should always be the judge, of course, but the standard C implementation seems better suited to most other Python applications. Still, that leaves a very substantial domain to Jythonalmost all Java systems and programmers can benefit from adding Jython to their tool sets.

因为上述原因,Python语言的Jython实现最好仅用于特定环境,即当Java集成或浏览器互用性是一个重要的设计目标时。但是标准C实现看起来能更好地适用于大多数其它Python应用。当然,你才是决定者。Jython仍然具有很大的应用领域,几乎所有Java系统和程序员都可以受益于Jython。

Jython allows programmers to write programs that use Java class libraries in a fraction of the code and complexity required by Java-coded equivalents. Hence, Jython excels as an extension language for Java-based systems, especially those that will run in the context of web browsers. Because Java is a standard component of most web browsers, Jython scripts will often run automatically without extra install steps on client machines. Furthermore, even Java-coded applications that have nothing to do with the Web can benefit from Jython's ease of use; its seamless integration with Java class libraries makes Jython arguably the best Java scripting and testing tool available today.

Jython允许程序员使用Java类库编程,与相同功能的Java编码相比,其代码量和复杂性仅是个零头。因此,Jython是Java系统上一种优越的扩展语言,特别是运行于浏览器环境下。因为Java是大多数浏览器的标准部件,Jython通常能够自动运行,而不需要客户机额外地安装步骤。另外,即使Java编码的应用程序与Web无关,也能从Jython的易用性上受益;Jython与Java类库的无缝集成使它成为当前最好的Java脚本与测试工具。

For most other applications, though, the standard Python implementation, possibly integrated with C and C++ components, is probably a better design choice. The resulting system will likely run faster, cost less to ship, have access to all Python extension modules, be more robust and portable, and be more easily maintained by people familiar with standard Python.

然而,对大多数应用来说,可与C和C++部件集成的标准Python实现,可能是更好的设计选择。这样系统会更快,发布成本更低,可使用所有扩展模块,更健壮和更好的移植性,以及更容易维护,只要人们熟悉标准Python。

On the other hand, I want to point out again that the trade-offs listed here are mostly written from the Python perspective; if you are a Java developer looking for a scripting tool for Java-based systems, many of these detriments may be of minor concern. And to be fair, some of Jython's problems may be addressed in future releases; for instance, its speed will probably improve over time. Yet even as it exists today, Jython clearly makes an ideal extension-language solution for Java-based applications, and it offers a much more complete Java scripting solution than those currently available for other scripting languages.[*]

另一方面,我要再次指出,这里列出的权衡是从Python的观点看的;如果你是Java开发者,正在为基于Java的系统寻找一种脚本工具,这些不利因素可能许多都是不值一提的。而且公正地说,Jython的一些问题可能会在将来版本中解决;例如,将来速度可能会提高。即使就目前的样子,Jython仍是 Java应用理想的扩展语言解决方案,比起当前可用的其它脚本语言,它提供了更为彻底的Java脚本解决方案。[*]

[*] Other scripting languages have addressed Java integration by reimplementing a JVM in the underlying scripting language or by integrating their original C implementations with Java using the Java native call interface. Neither approach is anywhere near as seamless and powerful as generating real Java bytecode.

[*] 其它脚本语言解决Java集成的方案是用该脚本语言重新实现一个JVM,或者脚本用C语言实现,并通过Java本地调用接口与Java集成。无论哪种方法都不能达到生成真正的Java字节码那样的无缝与有效。

For more details, consult the Jython home page, currently maintained at http://www.jython.org. You will also find commercially published books about Jython as well; search the Web for pointers. See also the sidebar "The IronPython C# Python Compiler," later in this chapter, about the new Python implementation for the C#/.NET environment on Windows (and its Mono open source equivalent). Though still emerging, it seems likely that there will be three Pythons to choose from very soon and perhaps more in the future. All will likely implement the same core Python language we've used in this text, but they may emphasize alternative integration schemes, application domains, development environments, and so on.

更多详情,请查阅Jython主页,目前是在http://www.jython.org。你也能搜索网络找到出版的有关Jython的书籍。也请翻阅本章下面的边栏“IronPython C# Python编译器”,那是Windows平台上C#/.NET(及开源的Mono)环境下Python的新的实现。虽然是新兴的,看起来不久就可以有三种Python供选择了,可能将来会更多。所有实现应该都实现同样的核心Python语言,但是它们可能侧重于不同的集成方案,应用领域,开发环境等等。



(转载请注明来源于金庆的专栏)

你可能感兴趣的:(Python)