[历史归档]本文原发布于 cstriker1407.info 个人博客内容为历史存档仅供参考。发布时间2013-12-27 标题jython学习笔记基础知识备忘录1分类编程 / python jython 标签python jythonjython学习笔记基础知识备忘录1退出 JythonJython 源文件是模块复数序列范围注释序列例子语句语法动态代码求值Eval、exec 和 execfile关于模块和导入模块和包import 语句导入的例子导入模块和包import 是可执行的子集导入运行本机应用程序Jython 异常关于异常try-except-else 语句访问异常信息try-finally 语句raise 语句del 语句:def 语句:指定函数参数处理可变参数global 语句嵌套函数最近在学习【 jython 】这门语言。这里备份下一些基本知识。本文部分内容来源至 IBM 的两篇非常不错的博文版权属于原作者但是原文链接已经失效了作者从网上找了一份网站的备忘后续把下载链接放上来。退出 Jython在 Jython 提示符下输入下列命令 import sys; sys.exit();或者可以按 CtrlC 两次。例子#最基本的打印 print 1,2,3;输出1 2 3Jython 源文件是模块Jython 源文件可以包含一系列要执行的语句。它们还可以包含函数和类定义。 实际上Jython 源文件可以是模块而模块不能直接使用要由其他程序导入。单个源文件可以扮演两种角色。请考虑上一屏中该文件的变体如下所示deffac(x):ifx1:return1returnlong(x)*fac(x-1)if__name____main__:print12printHelloGoodbyeprintfac(3)printfac(100)如果文件被导入到另一个只希望重用fac 函数的程序中则 if 请参见 if 语句测试条件下的任何一个语句都不执行。还要注意每个模块都有一个名称从命令行直接执行的名称为 “__main__”。该特性可用于为每个模块创建测试案例。复数 x 12j print x (12j) print x.real 1.0 print x.imag 2.0序列序列在 Jython 中是一种抽象概念因为您不能直接创建序列只创建从序列派生而来的子类型。任何序列子类型都具有序列的全部函数。序列子类型有几个如下所示字符串是字符的不变序列请参见 字符串。元组是任何数据类型的不变序列请参见 元组。范围是整数的不变序列请参见 范围。列表是任何数据类型的可变序列请参见 列表。范围要实现迭代请参见 for 语句Jython 使用整数递增的不可变序列。这些序列称为范围。采用两个内置函数很容易创建范围range({start,} end {,inc}) 创建一个小范围。该范围的所有元素都存在。xrange({start,} end {,inc}) 创建一个大范围。仅在需要时创建元素。注释Jython 包含两种形式的注释备注remarks 是用 sharp (#) 字符引入的注释。# 之后的同一行所有文本都被忽略。备注可以从任何列开始。文档注释documentation comments是紧接在外部块如模块、类和函数之后的字符串常量。字符串不改变外部块的行为而注释可以通过特殊属性 __doc__ 访问以创建块的描述。例子deffac(x):This is a function documentprintfac.__doc__;输出Thisisa function document序列例子#列表 x[0,1,2,3,4,5]; print x: ,x; print x[1]: ,x[1]; print x[1:3]: ,x[1:3]; print x[2:]: ,x[2:]; print x[:3]: ,x[:3]; print x[-3:]: ,x[:-3]; print x[:-3]: ,x[-3:]; print x[:]: ,x[:]; print xx: ,xx; print x*2: ,x*2; print 2*x: ,2*x; x[1,A]; print x: ,x; x[1,[2,Hello Wrold],X,3]; print x: ,x; #元组 x(1,); print x; x(1,2,3); print x; x(1,A,2,B); print x; x(1,A,(x,y,3),4,Hello World); print x; x(1,A,[1,2,3],4,Hello World); print x; #范围 print range(1,10): ,range(1,10); print range(1,10,3): ,range(1,10,3); print xrange(1,10): ,xrange(1,10); print xrange(1,10,3): ,xrange(1,10,3); #字典 x{1:A,2:B}; print x: ,x; print x[1]: ,x[1]; #error #print x[3]: ,x[3]; x{A:This is a string,2:[1,2,3],abc:(a,b,c),4:None}; print x: ,x; print x[A]: ,x[A]; print x[2]: ,x[2]; print x[\abc\]: ,x[abc]; print x[4]: ,x[4];输出x: [0, 1, 2, 3, 4, 5] x[1]: 1 x[1:3]: [1, 2] x[2:]: [2, 3, 4, 5] x[:3]: [0, 1, 2] x[-3:]: [0, 1, 2] x[:-3]: [3, 4, 5] x[:]: [0, 1, 2, 3, 4, 5] xx: [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5] x*2: [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5] 2*x: [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5] x: [1, A] x: [1, [2, Hello Wrold], X, 3] (1,) (1, 2, 3) (1, A, 2, B) (1, A, (x, y, 3), 4, Hello World) (1, A, [1, 2, 3], 4, Hello World) range(1,10): [1, 2, 3, 4, 5, 6, 7, 8, 9] range(1,10,3): [1, 4, 7] xrange(1,10): xrange(1, 10) xrange(1,10,3): xrange(1, 10, 3) x: {2: B, 1: A} x[1]: A x: {2: [1, 2, 3], A: This is a string, 4: None, abc: (a, b, c)} x[A]: This is a string x[2]: [1, 2, 3] x[abc]: (a, b, c) x[4]: None语句语法从以上各节可以知道Jython 的语法很简单。它与英语非常类似而不像 C 和 Java 语言。具体来说每个源代码行通常是单个语句。除了 expression 和 assignment 语句外每个语句都由关键字名称如 if 或 for引入。在任意两个语句之间都可以加空行或备注。不需要在每行的结尾加分号但如果愿意也可以加。如果希望每行包含多条语句则需要用分号来分隔语句。如有必要语句可以延续到超过一行。将一个反斜杠字符放在一行的末尾可以延续到任意行如下所示x A looooooooooooooooooooooooooooooooong string \ another looooooooooooooooooooooooooooooooong string判断和循环例子pass;a,b,c1,2,3;printa,b,c;abc100;printa,b,c;ifnotNone:printNone is False;ifnot0:print0 is False;if-1:print-1 is True;ifx0:printblock if;elifx1:printblock elif1;elifx2:printblock elif2;else:printblock else;x3;whilex0:x-1;printx;forvin(1,2,3):printv;fork,vin{1:A,2:B,3:C}.items():printk,v;输出1 2 3 100 100 100 None is False 0 is False -1 is True block elif1 2 1 0 1 2 3 3 C 2 B 1 A动态代码求值Jython 与一般的语言不同它有能力动态创建代码然后执行。例如在计算器应用程序中用户可以用文本形式输入表达式Jython 可以直接执行该表达式假设它符合 Jython 源代码规则。要较好地了解 Jython 如何对动态代码解释/求值请考虑下列代码v1 100; v2 200 l1 [1, 2, v1, v2] d1 {simple:123, complex:(v1, v2, l1)} expr raw_input(Enter an expression:) print eval(expr) # evaluate and print the expressionEval、exec 和 execfileeval 函数用于执行返回值的表达式。exec 语句用于对不返回值的代码块一条或多条语句进行求值它将文件、字符串常从文件中读取或函数作为自己的源操作数。execfile 函数执行来自文件的代码块它实际上是运行一个子程序。exec 语句采用下列形式exec source {in globals {, locals}}execfile 和 eval 函数采用下列形式execfile(filename, {globals {, locals}}) eval(expression, {globals {, locals}})所有三种形式都有选择地采用定义全局名称空间和局部名称空间的两个字典。如果省略了这些字典则使用当前的局部名称空间由 locals 函数提供和当前的全局名称空间由 globals 函数提供。例如如果字典 gd {“one”:1, “two”:2} 和 ld {“x”:100, “y”:-1} 用作名称空间则 print eval(“one two * 2 x y”, gd, ld)输入结果为104。关于模块和导入Jython 将程序分成不同的文件称为模块。通过将模块导入代码中模块就能被重用。Jython 提供了许多可以重用的模块请参见附录 FJython 库汇总。Jython 还允许重用任何 Java 类和 API。模块和包模块是可执行的 Jython 文件其中包含变量、函数和类等的定义。模块被导入执行和绑定到其他程序/脚本或模块中。当导入程序或模块需要使用导入模块中的一些或所有定义时就有必要导入模块。Jython 包是概念上有层次结构的模块的集合。它们以目录的方式实现的这些目录包含一个或多个模块和特殊文件 __init__.py该文件在包中第一个模块执行之前执行。模块和包允许重用扩展标准 Jython 和 Java 库。您还可以创建在自己的 Jython 应用程序中重用的模块和包。有关可用的 Jython 模块的更多信息请参见 附录 FJython 库汇总 。有关可用的 Java 库的更多信息请访问 Sun Microsystems 的 Java 技术主页在 参考资料 中。import 语句import 语句执行另一个文件并将绑定在它中的某些或所有名称都添加到当前名称空间中请参见 可见性和作用域。在导入文件中当前名称空间一般是全局名称空间。该模块中的所有语句包括赋值语句都被执行。import 语句有几种形式import module {as alias} -- or -- from module import name {as alias} -- or -- from module import *module 值将 Jython (.py) 文件或加点的路径命名为 Jython 包。name 值从模块中选择特定的名称。模块名称是区分大小写的。这些参数可以重复。可选择的 alias 值允许对导入的对象重新命名。导入的例子下面是一些 import 语句的例子例子注释import sys导入 sys 模块。sys 中的所有名称都可以通过前缀 sys 来引用。from sys import exc_info从 sys 模块导入 exc_info 函数。不需要前缀。from sys import *导入 sys 模块中的所有名称和函数。不需要前缀。from sys import exc_info as einfo从 sys 模块中导入 exc_info 函数并将其命名为 einfo。不需要前缀。from string import uppercase as uc, lowercase as lc从模块 string 中导入 uppercase 和 lowercase 函数。不需要前缀。import sys, string导入模块 sys and stringimport com.ibm.tools.compiler as compiler从 com.ibm.tools 包中导入 compiler并取一个短名称 compiler。导入模块和包要导入模块或包Jython 必须能找到相关的源文件 (.py)。Jython 使用 Jython 注册表中的 python.path与 Java 语言的 CLASSPATH 非常类似和 python.prepath 变量来搜索这些文件。您可以使用任何文本编辑器来添加或更新 Jython 主目录通常为 c:\jython-2.1中的 registry 文件。有关更多信息请参见 Jython 注册表在 参考资料 中或 registry 文件本身。默认情况下Jython 将搜索包含执行源文件的目录因此可以找到与正在导入的 Jython 程序位于同一个目录中的模块。当前目录通常也在该路径中。只要输入下例命令就可查出当前搜索路径importsysprintsys.path要找到 Java 类文件Jython 既搜索 Java CLASSPATH也搜索 sys.path 值。import 是可执行的与 Java 语言不同import 语句在 Jython 中是可执行的但它不是编译器指令。因此不需要在模块开始就执行导入而仅在使用已导入符号imported symbols之前执行。实际上导入可以有条件地完成如下例所示# lots of other stuff:if__name____main__::fromsysimportexit exit(0)导入也可以被撤销如下所示importsys:# lots of other stuff:delsys子集导入当导入模块时已赋值的所有值或在模块中创建的函数通常都可以由模块导入程序importer引用。您可以通过改变模块中的代码来防止出现此类情况。以下划线 (_) 作为名称的开头或在模块的开始定义一个特殊的变量 __all__这样可以只列出要导入的变量或函数的名称。例如下列 __all__ 定义__all__ [getline,clearcache,checkcache]只导入名称 getline、clearcache 和 checkcache。在模块目录级别可以采用类似的策略。在名为 __init__.py 的文件中定义变量 __all__指示解释器要从模块中导入哪些模块如果在导入语句中使用了通配符 (*)。例如如果 __all__ [‘mod1’, ‘mod3’, ‘globals’] 行位于名为 modules 目录下叫做__init__.py 的文件中它将导致语句 from modules import * 从 modules 目录导入模块 mod1、mod3 和 globals。运行本机应用程序通过 os.system 函数Jython 还可以运行任何在当前主机 PATH 中找到的外部程序如主机操作系统应用程序。例如要编译 Java 程序可以使用importosimportsys cmdjavac %(name)s.java 1%(name)s.out 2%(name)s.err%\{name:sys.argv[1]})rcos.system(cmd)ifrc0:printSuccessfulelse:printFailed: return code%i...%rc# read and process the .err file...Jython 异常关于异常不论程序员是如何仔细设计和测试其代码都可能发生意外错误即异常。Jython 为恢复这些错误提供了优异的支持。异常通常是 Jython 类型 exceptions.Exception 或 Java 类 java.lang.Exception 的子类。大多数 Jython 异常名称都以 “Error”例如IOError 或 IndexError 或 Warning结尾。而 Java 异常以 “Error”适用于关键异常或 “Exception”适用于一般可恢复异常结尾。有关更多信息请参见 Jython 异常层次结构 或 Python Library Reference请参见 参考资料 获得一个链接。try-except-else 语句与 C 和 Java 语言类似Jython 支持异常处理程序。这些处理程序由 try-except-else 语句定义该语句具有如下所示的形式try: statement except type, var: statement : else: statement -- or -- try: block except type, var: block : else: block可以用不同的 type 值重复 except 子句。如果这样异常就不能有重叠的层次结构即成为“兄弟”或者必须按子异常到根异常的顺序进行排序。可选的 type 值是一个异常类型或者是 exceptions.Exception 的子类或者是 java.lang.Throwable 的子类。如果缺少 type则 except 子句捕获所有 Jython 和 Java 异常。可选的 var 值接收实际的异常对象。如果缺少 var则异常对象是不能直接访问的。else 子句是可选的。只有在没有发生异常时才执行该语句。如果在 try 子句中发生了异常则该子句退出进入第一个匹配的 except 子句如果有。如果匹配不到异常则包含 try-except-else 的块退出且重新引发异常。如果异常在 except 或 else 子句中引发则该子句将退出而新异常将在包含块中得到处理。访问异常信息要访问有关异常的信息可以使用上面描述的 except 子句中的值或 sys.exc_info 函数。例如您可以使用下列函数其中type 是异常的类value 是异常对象使用 str(value) 来获得该消息traceback 是执行跟踪它是执行跟踪框架的链接表。importsys:try::except:type,value,tracebacksys.exc_info()try-finally 语句与 C 和 Java 语言一样Jython 还支持结构 try-finally采用该结构可以轻松地执行必需的清除活动如关闭打开的文件、释放资源等。一旦进入 try 子句finally 子句中的任何代码都要保证执行一次即使通过返回语句请参见 return 语句或异常退出也是如此。try-finally 语句具有下列形式try: statement finally: statement -- or -- try: block finally: blockraise 语句异常由被调用函数或内置服务生成。还可以使用 raise 语句生成异常。raise 语句具有下列形式raise exception -- or -- raise exception_class {, message} -- or -- #### raise例子注释raise重新引发当前的异常在异常块中用于重新生成异常raise IOError创建和引发 IOError没有消息raise anIOError重新引发现有的 IOError 对象raise IOError, “End of File”创建和引发 IOError有解释性消息from java import io raise io.IOException, “End of File”创建和引发 Java 异常有解释性消息例子import sys; try: x 1/0; except: print traceback,sys.exc_info(); else: print x; finally: print finally block;输出traceback (, ZeroDivisionError(integer division or modulo by zero,),) finally blockdel 语句:可变的序列请参见 序列类型 、映射请参见 映射和字典和类都支持 del 语句该语句分别从集合或类中删除元素或属性。对序列而言删除是按索引进行的而对映射是按键值对类是按属性名称。我们将在本教程的第 2 部分详细讨论 del 语句的类支持。局部或全局变量可以被删除这将从名称空间中删除变量它不删除变量所引用的对象。del 语句还支持切片表示法slice notation。假设 “l” 是列表 [1,2,3,4,5]d 是字典 {1:“one”, 2:“two”, 3:“three”}而 x 某个类实例下面是一些 del 语句的例子例子注释del l[0]删除第一个元素del l[1:3]删除第二个到第三个元素del l[::2]删除偶数元素del l[:]删除所有元素del d[1]删除带有键的元素1del x.attr1删除属性attr1var [1,2,3] : del var从名称空间中删除变量vardef 语句:在 Jython 中函数通过 def 语句声明该语句具有以下形式defname(args):statement--or--defname(args):block在给定的作用域模块、函数或类内每个函数名都应是惟一的。函数名事实上是绑定到函数体的变量类似于任何其他赋值。实际上可以定义多个变量来引用同一个函数。函数体可以是单个语句通常是一个返回语句也可以是语句块这种情形更为常见。指定函数参数例子注释def x(a, b, c)定义有三个必需位置参数的函数def x(a, b, c1)定义有三个参数的函数最后一个参数是可选的其默认值为 1def x(a3, b2, c1)定义有三个参数的函数这三个参数都是可选的都有默认值def x(p1, p2, kw11, kw22)定义一个有两个位置参数和两个关键字可选参数的函数。声明该函数时所有可选参数值参数必须在所有非可选参数之后。调用该函数时关键字参数如提供可以在位置参数之后按名称以任何顺序指定def x(p1, p2, *v)定义一个具有两个必需位置参数和数量不确定的变量参数的函数。v 变量将是一个元组def x(p1, p2, **kw)定义一个具有两个必需位置参数和数量不确定的变量参数的函数。kw 变量是字典。def x(p1, p2, *v, **kw)定义一个具有两个必需位置参数和数量不确定的位置和关键字参数的函数。v 变量是元组。kw 变量是字典。处理可变参数如果参数接受可变对象如列表和字典的默认值则最好采用下列形式def x(p1, p2, p3None) if p3 is None: p3 [] :例子#函数sumfunlambdax,y:xy;printsumfun(1,2);deffun1(a,b,c1,*d,**e):printa,a;printb,b;printc,c;printd,d;printe,e;fun1(A,B);fun1(A,B,C);fun1(A,B,C,D,E,F);fun1(A,B,C,D,E,F,aaaM,xxxN);deffun2(a,bNone):printa,a;printb,b;fun2(3,[A,B]);fun2(3,{A:100,B:200});输出a A b B c 1 d () e {} a A b B c C d () e {} a A b B c C d (D, E, F) e {} a A b B c C d (D, E, F) e {aaa: M, xxx: N} a 3 b [A, B] a 3 b {B: 200, A: 100}global 语句有时您可能希望在局部上下文中声明变量即赋值但在全局作用域中引用变量。为此请在第一次使用变量前使用 global 语句。下面是一个例子x10;y20;z30# three global variablesdeff1(p,q,r):xp# local x, y z variablesyq zrdeff2(a,b,c):globalx,y xa# global x y variablesyb zc# local z variableprintx,y,z# prints: 10, 20, 30f1(1,2,3)printx,y,z# prints: 10, 20, 30f2(-1,-2,-3)printx,y,z# prints: -1, -2, 30注意只要全局变量没有被局部地重新绑定那么在没有将其声明为全局的情况下就可读取该变量。因此只有在对全局变量赋值时才需要 global 语句。嵌套函数与许多其他语言包括 Java 语言不同Jython 允许在其他函数内部定义函数。嵌套或局部函数有助于缩减函数的作用域。下面是一个例子defx(a,b,c):ya*bdefsquare(x):returnx**2# this x is different from function xy*square(c)returnx包含函数中的变量对嵌套函数是不可见的。如果嵌套函数必须使用这些值则将这些值作为参数传递给嵌套函数。例如下列函数def calc(a, b, c): x a * b * c def sum(data): # cannot access calcs namespace (x, a, b, c, or sum) here print locals() return data[a] data[b] data[c] x sum(locals()) return x print calc(10,20,30)输出{data:{x:6000,c:30,b:20,sum:\functionsumat32308441,a:10}}6060使用嵌套函数还能方便地创建预先配置要作为结果返回的函数如下所示def makeSq(n): def sq(xn): # ns value is saved as the parameter x value return x ** 2 return sq上述函数可以像下面这样使用sq2 makeSq(2) print 2*2%i % sq2() # prints: 2*24 sq10 makeSq(10) print 10*10%i % sq10() # prints: 10*10100