Perl 与 Python 之间的一些异同整理

关于 Perl 与 Python 的起源和特点

Perl 是 Practical Extraction and Report Language 的简称,由 1987 年 Larry Wall 创建,最初的目的是为了在 UNIX 上方便处理报表,经过长期的发展已经成为一种全功能的程序设计语言,当前最新的版本为 Perl5.14.1,Perl 作为一种自由而强大的编程语言,其中心思想是: There's More Than One Way To Do It。(不只一种方法來做这件事 ),即「 Tim Toady 」。作为一种“胶水型”语言,它具有强大的正则表达式和模式匹配功能以及灵活的数据结构,如动态数组、Hash 等,在语法规则上借鉴了 C/C++、Basic、Pascal 等语言,其不足之处在于存在一些冗余语法,代码的可读性较差。

Python 是一种基于面向对象的解析性交互式的开源编程语言,它起源于 1989 年末由 CWI(阿姆斯特丹国家数学和计算机科学研究所)的研究员 Guido van Rossum 创立,1991 年初公开发行,其开源式的发行方式促进了 Python 的较快发展,目前已经形成了一个强大的社区力量。Python 开发者的哲学是“用一种方法,最好是只有一种方法来做一件事”。Python 具有简单易学、代码规范、语法简单、可移植性强、支持多平台、类库丰富等优点。
Perl 和 Python 都是开源的,但其哲学理念却刚好相反,因此常被人们将这两种语言放在一起进行比较。下面的篇章将从基本数据类型、控制流、函数、面向对象、文本处理等方面对这两种语言进行简单的比较和鉴别。

Perl 与 Python 的基本数据类型

脚本语言支持多种数据类型,变量无需事先申明,类型根据值来动态确定,一个变量在程序中可以根据上下文环境的不同存储不同类型的值。

Perl 支持的基本数据类型包括:标量、数组、哈希。在定义的时分别用 $、@、% 表示。

标量 (scalar):标量是 Perl 中最简单的数据类型,大多数标量由数字或字符串组成。其中数字类型如整数、浮点数等,字符串有单引号和双引号内两种形式,对长度没有限制。两者的区别在于在单引号内 \n 不代表换行,而代表反斜线和 n 这两个字符,双引号内字符串则可以通过反斜线进行转义。字符串的操作符有 . 拼接操作符和 x 重复操作符等。
数组 (Arrays):数组用 @ 定义,如 my @array=("a","b","c","d"); 访问数组的元素用 $array[1]。在 perl 中,数组也可以当做堆栈来处理,支持的操作符包括 pop 和 push,shft 和 unshift。两组操作的区别在于前者对数组的尾部进行处理,而 shift 和 unshift 则针对数组的头部进行处理。pop 得到的是数组的最后一个元素,如 pop(@array)= d,如果数组为空,则返回 undef。而 shift(@array)=a。
哈希:也称作关联数组,是根据关键码值 (Key value) 而直接进行访问的数据结构。用 % 定义,如 %my_hash=(“key1”=>”23”,”name”=>”zhang”,”age”=>”24”),其中键以字符串表示,Hash 可以是任意大小。
与 hash 相关的函数有:
keys:返回 hash 的键列表 my @keylist = keys %hash
value:返回值列表 my @valuelist = values %hash
each:用两个元素的列表返回键值对。


代码如下:

while(($key,$value)= each %hash)
{
print “$key =>$value\n”;
}

Python 支持五种基本数据类型:数字 (Numbers)、字符串 (String)、列表 (List)、元组 (Tuple) 和字典 (Dictionary)。其中数字和字符串和 perl 中的标量对应,列表和数组对应,元组可以看做是不可变的列表,字典和 hash 对应。

数字 (Numbers):Python 支持五种基本数字类型,分别为 int( 有符号整数 ) 、long( 长整数 ) 、bool( 布尔值 ) 、float( 浮点数 ) 、complex( 复数 )。
字符串 (String):Python 与 Perl 一样也支持单引号和双引号字符串,但与 Perl 不同,转义字符在单引号中也会起作用。同时 python 还支持三引号字符串,它允许一个字符串跨多行,字符串中可以包含换行符,制表符以及其他特殊字符。三引号字符串常用于注释或者形成文档。字符串支持成员操作符 in,not in,连接操作符 + 以及重复操作符 *。Python 字符串可以当做 list,支持切片操作符 [],[:] 和反向索引。如下:
如 aString=”abcd”;则 aString[0] 的值为 a,aString[1:3]=bc,反向索引 aString[-1]=d
列表 (List):Pyhon 中的列表与 Perl 中的数组相对应。列表的定义使用 []. 如 li = ["a", "b", "mpilgrim", "z", "example"] ,支持动态增加和删除元素以及切片操作。
增加元素可以使用 li.append(“test”),li.insert(2,”new”) 以及 li.extend([“f”,”ggf”])
删除元素使用 li.remove(“f”) 和 li.pop() 。但需要注意的是 remove 仅删除首次出现的,而 pop 会删除 list 最后的一个元素,然后返回删除的元素的值。
元组 (Tuple):元组和列表非常相似,但用()表示,并且元组是不可变的。
字典 (Dictionary):字典跟 Perl 中的 hash 一样,定义了键值对之间一对一的关系,变量可以任意取名,Python 会在内部记录其数据类型。定义一个字典:D={“name”:”Jon”,”Family”:”SH”}, 字典中的 key 是不能重复的,并且大小写敏感,同时字典中的元素是无序的。字典也支持增删操作,往字典中添加元素 D[“age”]=23, 删除元素 del D['name'],如果需要删除所有元素可以使用 D.clear(), 或者 del D 删除整个字典。

Perl 与 Python 的控制结构

在控制结果方面,Perl 较 Python 丰富,除了支持传统的 if 、while 、for 控制结构,还支持 until 、unless 、foreach 等,Python 的控制结构相对要少一些,但已经能够满足语言的要求。本节对这些控制结构进行详细比较。

If 控制结构:

Perl 与 Python 都支持 if 、if-else 、if-else if- else 三种结构,两者在语法上基本类似,但与 Python 不同的是 Perl 中没有 boolean 类型,零和空表示 False,其余表示 True,而 Python 中除了''、""、0、()、[]、{}、None 为 False 之外,其他的都是 True。同时 Python 直接用缩进表示 block 块。

表 1. if 控制结构


















Perl Python
if if (expression) {
true_statement;
}
if expression:
if_suite
if-else if (expression) {
true_statement;
}
if expression:
if_suite
else:
else_suite
If-else if-else if (expression_A) {
A_true_statement;
} elseif (expression_B) {
B_true_statement;
} else {
false_statement;
}
if expression1:
if_suite
elif expression2:
elif_suite
else:
else_suite


Perl 中还支持 unless 条件控制语句,基本语法如下:

unless (expression) {
stmt_1; }

unless 和 if 不同之处在于当条件表达式的值为假的时候才执行,同时 unless 后面还能跟 else 语句。如:


代码如下:

unless($mon =~/^Feb/){
print “This month has at least thirty days.\n”;
}else{
print “Do you see what's going on here?\n”;
}

循环控制结构:

For 循环:
Perl 中的 for 循环除了支持传统的 for 循环,即 for ( 表达式 1; 表达式 2; 表达式 3) ,还支持 foreach 语句,基本语法为:


代码如下:

foreach $i (@aList) {
stmt_1;
}

python 不支持传统的 for 循环,但是提供了强大的循环结构可以遍历序列成员,同时 for 循环后面也可以接 else 语句,基本语法如下:

for inter_var in iterable:
suite_to_repeat
else:
else_statement

while 循环
Perl 循环控制结果还支持 while 和 do-while 以及 until 形式,until 与 while 结构相似,区别在于 unitl 会在条件为假的时候重复执行。until 语法如下:


代码如下:

until(expression)
{
statement;
}

而 python 只支持 while 形式,但 python 可以在 while 后面接 else 语句。语法如下:

While condition:
statements
else:
statements

循环控制符

Perl 有三个循环控制操作符,分别为 Last 、next 、redo。

last:立即终止循环,类似于 c 中的 break。在多层循环中,只对 last 所在的当前循环块有效;
next:立刻结束当前这次迭代;
redo:将控制返回本循环的顶端,不经过条件测试也不会进去下一次迭代循环,而是重新执行本循环块。它与 next 最大的区别在于 next 会正常继续下一次迭代,而 redo 会重新执行本次迭代。

Python 也有三个循环控制操作符,分别为 break 、continue 、pass 语句。

break:与 C 中的 break 类似;
continue:continue 语句并不会退出循环结构,而是立即结束本次循环,重新开始下一轮循环,也就是说,跳过循环体中在 continue 语句之后的所有语句,继续下一轮循环;
pass:一般作为占位符或者创建占位程序,pass 语句不会执行任何操作。

Perl 与 Python 的函数

Perl 和 Python 都支持函数,可以传递参数以及在程序中对函数进行调用等。下面从函数的定义,调用,返回值以及参数传递等方面对这两者进行比较。
表 2. Perl 与 Python 函数比较





















Perl Python
定义
  1.  基本语法:
sub functionName{
       statement;
[return value]
     }

  1. 基本语法:
    def functionName(arg1,arg2,[...]):
    statement
    [return value]

  2. 内嵌函数:
    Python 支持内嵌函数 , 其方法是在外部函数的定义体内定义函数 , 但整个函数体都在外部函数的作用域之内 .
    def outfun():
    def innerfun():
    Print “inner fun test”
    print “out fun test”
返回值 使用 return 语句显示返回;如果没有 return,默认返回最后一次运算的结果 使用 return 语句显示返回,没有 return 语句,默认返回为 None。如果函数返回多个对象,python 把他们聚集起来并以一个元组返回。
调用 & 函数名(参数 1,参数 2,...),如果声明在前,可以省略 &。如果用户所定义的子过程与内置函数重名,则不能省略 &。
如下例必须使用 &chomp 调用:
sub chomp{
print “it is my chomp\n”;
}

  1. 直接采用 函数名(参数 1,参数 2.....)
  2. 函数名(参数名 1= 值,参数名 2= 值 .......)
函数参数
  1. 在子程序调用的后面加上被括号圈引的列表表达式即可,所有的参数都会自动存储为 @_ 中,其中第一个参数为 $_[0], 第二个参数存储 $_[1]。
  2. 传递引用,在参数前加入 \ 表示为引用

  1. 按照参数声明的关键字顺序直接传递;
  2. 通过关键字参数 testFun(par1=“2”,par2=“45”)
  3. 默认参数:
    > Python 在传递参数的时候支持默认参数,规则是所有的位置参数必须出现在任何一个默认参数之前,如
    def fun(arg1,defarg1=”var1”,defarg2=”12”), 如果在调用的时候没有给出参数值,则会使用默认值

  4. 变长参数:
    一种方法是利用非关键字可变长参数 , 可变长的参数元组必须在位置和默认参数之后 , 带元组的函数语法如下:
    def function_name([formal_args,]*vargs_tuple):
    function_body
    其中 * 之后的形参将作为元组传递给函数。

    另外一种方法是利用关键字变量参数,区别是在函数的参数变量里使用 **。
    def dicVarArgs(arg1,arg2=”default”,**theRest):
    print 'formal arg1:', arg1
    print 'formal arg2:', arg2
    for eachXtrArg in theRest.keys():
    print 'Xtra arg %s: %s' % \(eachXtrArg, str(theRest[eachXtrArg]))

Perl 与 Python 的包与模块

Perl 程序把变量和子程序的名称存贮到符号表中,Perl 的符号表中名字的集合就称为 Perl 包 (package)。定义语法为:package mypack;每个符号表有其自己的一组变量、子程序名,各组名字是不相关的,因此可以在不同的 Perl 包中使用相同的变量名,而代表的是不同的变量。Perl 模块有两种来源,一种是随 Perl 发行版本一同打包的,另外就是用 CPAN 中下载的。Perl 模块和包的概念并不清晰,两者有时可以混用。在程序中使用模块的操作称为导入模块;导入模块关键字 use;如:use ModuleName;模块被导入后,其中的子程序和变量就可以直接使用了;要取消一个已经导入了的模块,可以使用关键字 no;如:no ModuleName。
一个 .py 文件就是一个 python 模块。把一堆相关的 python 模块放在一个目录下,再加上一个 __init__.py 文件就构成了一个 python 包。在 Python 另一个程序中导入模块用 import module 或者 from module import *,两者的区别在于:import module 会导入 module 这个模块里的所有标识,但是这些标识现在都在 module 名字空间下。from module import * 也会导入 module 中所有标识,但是标识放到在当前名字空间里。
导入模块或包按下面顺序进行路径查找:
1. 当前目录
2. 环境变量 PYTHONPATH 所指的目录列表 3.python 解释器的安装目录
Perl 与 Python 中的 OOP
在 Perl 中,类是 Perl 包,含有提供对象方法的类,而方法是 Perl 的子程序,类名是其第一个参数,对象是对类中数据项的引用。在 Perl 中创建一个新类,首先要创建一个包,扩展名为 .pm, 在创建 perl 包的时候程序的最后一个必须为"1;";否则该包不会被 Perl 处理。

清单 1. 创建 perl 的类和对象


代码如下:

package person;
use strict;
sub new {
my $class = shift();
print("CLASS = $class\n");
my $self = {};
$self->{"name"} = shift();
$self->{"sex"} = shift();
bless $self, $class;
return $self;
}
1;
[html]
其中 new() 方法是对象的构造函数,是创建该类的对象实例必须被调用的,它返回该对象的引用。将类名与引用相结合称为”bless”一个对象,其语法为:bless YeReference [,classname]
YeReference 是对被”祝福”的对象的引用,classname 是可选项,指定对象获取方法的包名,其缺省值为当前包名。也可以通过函数 bless 来声明一个构造函数。
[code]
sub new
{
my $class = shift;
my $self = {};
bless $self, $class;
return $self;
}

创建一个对象可以直接使用 new 关键字。$object = new Person( "mohand", "sam", 345);
Perl 类中的方法就 Perl 的子函数,规定第一个参数为对象或者被引用的包,分为静态方法和虚方法。 虚方法通常首先把第一个参数 shift 到变量 self 或 this 中,然后将该值作普通的引用使用。一是通过该对象的引用 ( 虚方法 ),一是直接使用类名 ( 静态方法 )。如上例中如果类 Person 中有 getContactList 则可以直接使用 $object->getContactList() 来调用该方法。
Perl 支持重载,当两个不同的类中含有相同的方法名称的时候,可以用 :: 操作符指定使用哪个类中的方法。
$mess = Qava::grind("whole","lotta","bags");
Qava::grind($mess, "whole","lotta","bags");
由于 Perl 采用了简单的、基于引用的垃圾回收系统。Perl 跟踪对象的链接数目,当某对象的最后一个应用释放到内存池时,该对象就自动销毁。因此一般不需要定义类的析构函数。
Perl 通过数组 @ISA 支持继承。
package Employee;
use Person;
use strict;
our @ISA = qw(Person); # inherits from Person

当子类继承父类的时候,继承了父类的所有方法,但子类也可以覆盖父类的方法。如加入 Employee 想覆盖父类的 getFirstName:


代码如下:

#!/usr/bin/perl
package Employee;
use Person;
use strict;
our @ISA = qw(Person); # inherits from Person
# Override helper function
sub getFirstName {
my( $self ) = @_;
# This is child class function.
print "This is child class helper function\n";
return $self->{_firstName};
}
1;

调用直接使用 $firstName = $object->getFirstName(); 如果要调用父类的 getFirstName,则可以使用 $object->Person::getFirstName();
在 Python 中创建一个类的基本语法为 :
class className(bases):
classBody

参数 base 可以是一个单继承或者多继承的父类,object 是所有类的父类,位于类继承结构的最上层。类的构造函数为 __init__(),其中构造函数中 self 会作为第一个默认的参数。而类的析构函数则是 __del__(),访问类的方法和属性可以直接使用 . 访问符。
Python 不支持纯虚函数或抽象方法,并且声明和定义没有本质区别。一般或者 Python 类的属性可以通过 __dict__ 或者 dict()访问。常见属性有 __name__ ,__doc__,__base__,__dict__。Python 中创建一个类的实例,不需要关键之 new,直接使用类名 () 即可。如 c=myclass()。
Python 不仅仅支持单继承和多继承,同时还支持方法的覆盖 .


代码如下:

class P(object):
def foo(self):
print 'Hi, I am P-foo()'
>>> p = P()
>>> p.foo()
Hi, I am P-foo()

现在创建 C 类 , 继承于 P


代码如下:

class C(P):
def foo(self):
print 'Hi, I am C-foo()'
>>> c = C()
>>> c.foo()
Hi, I am C-foo()

当从一个带构造器 __init()_ 的类派生,如果在子类中覆盖了 __init__(),当子类被实例化时,基类的 __init__() 方法不会被自动调用。如果必须调用基类的构造方法,可以使用父类名 .__init__(self) 方法或者 super( 子类名,self).__init__()。 如


代码如下:

def __init__(self):
super(C, self).__init__()
print "calling C's constructor"

Python 类和实例支持一些内建函数,如
Issubclass(sub,sup):判断一个类是另一个类的子类或子孙类;
isinstance(obj1,obj2):判定一个对象是否是另一个给定类的实例;

Perl 与 Python 的正则表达式
正则表达式是 perl 比较突出的一大特色,perl 中正则表达式有三种形式:
匹配:m/<regexp>/ (还可以简写为 /<regexp>;/ ,略去 m) 替换:s/<pattern>/<replacement>/ ,为了语法的简化用 /<pattern>/<replacement>/ 表示,略去 s
转换:tr/<charClass>/<substituteClass>/ 这种形式包含一系列的字符— /<charClass> —同时把它们替换为 <substituteClass>。
表 3. Perl 常用匹配模式










































































































语法 说明 示例
. 匹配除换行符以外的所有字符 b.c 匹配 bac
x? 匹配 0 次或一次 x 字符串 b?c 匹配 c 或者 bc
x* 匹配 0 次或多次 x 字符串,但匹配可能的最少次数 b*c 匹配 c 或者 bbc
x+ 匹配 1 次或多次 x 字符串,但匹配可能的最少次数 b+c 匹配 bc 或者 bbc
.* 匹配 0 次或一次的任何字符 b.*c 匹配 bgdc 等
.+ 匹配 1 次或多次的任何字符 b.+c 匹配 bgc 等
{m} 匹配刚好是 m 个 的指定字符串 b{5}c 匹配 bbbbbc
{m,n} 匹配在 m 个 以上 n 个 以下 的指定字符串 b{1,2} 匹配 b 或者 bb
{m,} 匹配 m 个 以上 的指定字符串 b{2,} 匹配 bb 或者 bbb 等
[] 匹配符合 [] 内的字符 b[d]c 匹配 bdc
[^] 匹配不符合 [] 内的字符 b[^d]c 匹配 bAc
[0-9] 匹配所有数字字符 b[0-9]c 匹配 b1c
[a-z] 匹配所有小写字母字符 b[a-z]c 匹配 bac
^ 匹配字符开头的字符 ^perl 匹配以 perl 开头的字符
$ 匹配字符结尾的字符 perl$ 匹配以 perl 结尾的字符
\d 匹配一个数字的字符,和 [0-9] 语法一样 b\dc 匹配 b1c
\D 非数字,其他同 \d b\Dc 匹配 bAc
\w 英文字母或数字的字符串,和 [a-zA-Z0-9] 语法一样 b\wc 匹配 b1c 等
\W 非英文字母或数字的字符串,和 [^a-zA-Z0-9] 语法一样 b\Wc 匹配 b c
\s 空格,和 [\n\t\r\f] 语法一样 b\sc 匹配 b c
\S 非空格,和 [^\n\t\r\f] 语法一样 b\Sc 匹配 bac 等
\b 匹配以英文字母 , 数字为边界的字符串 \bbc\b 匹配 bc 但不匹配 bca
\B 匹配不以英文字母 , 数值为边界的字符串 sa\B 将匹配 sand 和 Sally 等字符串,而不能匹配 Melissa.
a|b|c 匹配符合 a 字符 或是 b 字符 或是 c 字符 的字符串
abc 匹配含有 abc 的字符串
匹配 a 或者 b 或者 c 等
(pattern) () 这个符号会记住所找寻到的字符串,是一个很实用的语法。第一个 () 内所找到的字符串变成 $1 这个变量或是 \1 变量,第二个 () 内所找到的字符串变成 $2 这个变量或是 \2 变量,以此类推下去。 b(\d)c 表示匹配的任何数字将存放与 $1 变量中

Python 语言本身不支持正则表达式,依赖 re 模块(python1.5 版本被引入)支持正则表达式。有搜索和匹配两种方法完成匹配模式。re 模块常用的函数和方法有 complie、match、search、find 与 findall 等。在利用 re 进行匹配之前,模式必须被编译成 regex 对象。

表 4. Python 常用匹配模式


















































































语法 说明 示例
. 匹配除换行符 \n 以外的任意字符 b.c 匹配 bac,bdc
* 匹配前一个字符 0 次或多次 b*c 匹配 c,或者 bbbc
+ 匹配前一个字符 1 次或多次 b+c 匹配 bc 或者 bbbc
匹配前一个字符 0 或 1 次 b?c 匹配 c 或者 bc
{m} 匹配前一个字符 m 次 b{2}c 匹配 bbc
{m,n} 匹配前一个字符 m 至 n 次 b{2,5}c 匹配 bbc 或者 bbbbc
[abc] 匹配 [] 内的任意字符 [bc] 匹配 b 或者 c
\d 匹配数字 [0-9] b\dc 匹配 b1c 等
\D 匹配非数字,等价于 [^\d] b\Dc 匹配 bAc
\s 匹配空白字符 b\sc 匹配 b c
\S 匹配非空白字符 [\^s] b\Sc 匹配 bac
\w 匹配 [A-Za-z0-9_] b\wc 匹配 bAc 等
\W 等价于 [^\w] b\Wc 匹配 b c
\ 转义字符, b\\c 匹配 b\c
^ 匹配字符串开头 ^bc 匹配句首的 bc
$ 匹配字符串末尾 bc$ 匹配以 bc 结尾的字符串
\A 仅匹配字符串开头 \Abc 匹配字符串开头的 bc
\Z 仅仅匹配字符串末尾 bc\Z 匹配字符串末尾的 bc
| 匹配左右表达式任意一个 b|c 匹配 b 或者 c

Perl 与 Python 中的线程
线程是一个单一的执行流程,它是所有程序执行过程中最小的控制单位,即能被 CPU 所调度的最小任务单元。在 Perl 中一个线程的生命周期包括创建,运行与退出这三个阶段。线程的运行过程与普通函数的执行类似,但新建线程的执行与当前线程的执行是并行的。
在 Perl 中创建线程有两种方法:

清单 2. 使用 threads 包的 create() 方法


代码如下:

use threads;
sub say_hello
{
printf("Hello thread! @_.\n");
return( rand(10) );
}
my $t1 = threads->create( \&say_hello, "param1", "param2" );

清单 3. 使用 async{} 块创建线程


代码如下:

#!/usr/bin/perl
use threads;
my $t4 = async{
printf("Hello thread!\n");
};

对于线程的执行控制,有两种方式,一种是 join(),一种是 detach()。所谓 join() 就是在主线程中等待子线程的执行返回值,然后再继续执行后续代码,而在调用线程的 join() 方法之前,子线程与主线程的执行是分开的。而 detach() 则是告诉解释器主线程不关心子线程的执行结果,所以该子线程在完成任务之后就是自动退出,同时释放自己所占有的资源,而不用主线程再操心。
Perl 默认任何数据结构都不是共享的,任何新创建的线程都有当前数据的私有拷贝。如果要共享数据,必须使用 threads::shard 进行显示声明。
如:


代码如下:

my $var :shared = 0; # use :share tag to define
my @array :shared = (); # use :share tag to define
my %hash = ();
share(%hash); # use share() funtion to define

同时 Perl 线程还支持锁机制,可以使用 lock 方法实现线程间共享数据的锁机制。Perl 中的 Thread::Semaphore 包为线程提供了信号量的支持,Thread::Queue 包为线程提供了线程安全的队列支持。更多使用读者可以自行查阅相关文档。
Python 提供了几个用于多线程编程的模块,包括 thread, threading 和 Queue 等。thread 和 threading 模块允许程序员创建和管理线程。thread 模块提供了基本的线程和锁的支持,而 threading 提供了更高级别,功能更强的线程管理的功能。Queue 模块允许用户创建一个可以用于多个线程之间共享数据的队列数据结构。
Python 的线程创建也有两种方式,一是利用 thread 模块的 start_new_thread() 函数来产生新线程。


代码如下:

import time
import thread
def timer(no, interval):
cnt = 0
while cnt<10:
print 'Thread:(%d) Time:%s/n'%(no, time.ctime())
time.sleep(interval)
cnt+=1
thread.exit_thread()
def test(): #Use thread.start_new_thread() to create 2 new threads
thread.start_new_thread(timer, (1,1))
thread.start_new_thread(timer, (2,2))

if __name__=='__main__':
test()

另一种是创建 threading.Thread 的子类来包装一个线程对象。


代码如下:

class timer(threading.Thread): # derived from the class threading.Thread
def __init__(self, num, interval):
threading.Thread.__init__(self)
self.thread_num = num
self.interval = interval
self.thread_stop = False
def run(self): #Overwrite run() method, put what you want the thread do here
while not self.thread_stop:
print 'Thread Object(%d), Time:%s/n' %(self.thread_num, time.ctime())
time.sleep(self.interval)
def stop(self):
self.thread_stop = True

Python 线程中也提供同步机制,可以利用 thrading 模块的 threading.RLock 和 hreading.Condition 可以分别实现锁机制和条件变量。
其中 acquire() 和 release() 方法分别获取和释放锁。


代码如下:

def run(self):
global x
lock.acquire()
for i in range(3):
x = x + 1
time.sleep(2)
print x
lock.release()

更多关于线程的内容,读者可查阅相关文档。
总结
本文从 Perl 和 Python 的起源,基本数据类型、控制结构、函数、包与模块、面向对象、正则表达式以及线程等方面进行了比较,从而给需要同时掌握这两种脚本语言的开发人员一定参考,以便更好的理解与应用。

参考资料学习

(0)

相关推荐

  • Python和perl实现批量对目录下电子书文件重命名的代码分享

    经常会遇到下载的文件或电子书,名字中间都包含了一些网址信息,实际使用中由于名字太长不方便,下面的脚本使用正则表达式来对目录下的所有文件重命名: 例如: 修改前:[我们]Mac OS X for Unix Geeks[www.jb51.net].mobi 修改后:Mac OS X for Unix Geeks.mobi python代码如下: 复制代码 代码如下: import os import re def rename_dir(dir,regex,f):   if not os.path.i

  • 用Python制作在地图上模拟瘟疫扩散的Gif图

    受杰森的<Almost Looks Like Work>启发,我来展示一些病毒传播模型.需要注意的是这个模型并不反映现实情况,因此不要误以为是西非可怕的传染病.相反,它更应该被看做是某种虚构的僵尸爆发现象.那么,让我们进入主题. 这就是SIR模型,其中字母S.I和R反映的是在僵尸疫情中,个体可能处于的不同状态. S 代表易感群体,即健康个体中潜在的可能转变的数量. I 代表染病群体,即僵尸数量. R 代表移除量,即因死亡而退出游戏的僵尸数量,或者感染后又转回人类的数量.但对与僵尸不存在治愈者,

  • Python和Perl绘制中国北京跑步地图的方法

    当你在一个城市,穿越大街小巷,跑步跑了几千公里之后,一个显而易见的想法是,我到底和之前比快了多少,跑量有何变化,如果能把在这个城市的所有路线全部画出来,会是怎样的景象呢? 1.数据来源:益动GPS 文章代码比较多,为了不吊人胃口,先看看最终效果: [/code] 首先需要有原始数据信息,手机上众多跑步软件提供了详细的记录,但它们共同的问题是不允许自由导入导出(可能是为了用户粘性吧).因此有一块智能运动手表应该是不二之选.我的是Garmin Fenix3,推荐一下: 益动GPS算是业界良心了,能够

  • 利用perl、python、php、shell、sed、awk、c 实现字符串的翻转

    原题: Q:有a.txt文件,里面内容如下 1234569 abcABCabc 要求使用awk打印出以下结果 987654321 cbaCBAcba A: shell  :[root@vps tmp]# rev a.txt 9654321 cbaCBAcbaperl : [root@vps tmp]# perl -nle 'print scalar reverse $_;' a.txt 9654321 cbaCBAcbaawk: [root@vps tmp]# awk '{num=split($

  • Python Mysql数据库操作 Perl操作Mysql数据库

    首先下载 MySQLdb #encoding=GBK import MySQLdb #import sys # #reload(sys) #sys.setdefaultencoding('utf-8') print 'Connection ...' host='192.168.1.77' user='root' passwd='123456' db='test' conn = MySQLdb.connect(host,user,passwd,db,charset='gbk') print 'Co

  • Shell、Perl、Python、PHP访问 MySQL 数据库代码实例

    下午写了一个简单的 bash 脚本,用来测试程序,输入一个测试用例文件,输出没有通过测试的用例和结果,然后把结果保存到数据库里.如何在 bash 脚本里直接访问数据库呢?既然在 shell 里可以直接用 mysql 命令操作数据库,那么在 shell script 里也应该可以通过调用 mysql 来操作数据库.比如用下面的 bash shell 脚本查询数据库: Bash 复制代码 代码如下: #!/bin/bash mysql -uvpsee -ppassword test << EOFM

  • Perl 与 Python 之间的一些异同整理

    关于 Perl 与 Python 的起源和特点 Perl 是 Practical Extraction and Report Language 的简称,由 1987 年 Larry Wall 创建,最初的目的是为了在 UNIX 上方便处理报表,经过长期的发展已经成为一种全功能的程序设计语言,当前最新的版本为 Perl5.14.1,Perl 作为一种自由而强大的编程语言,其中心思想是: There's More Than One Way To Do It.(不只一种方法來做这件事 ),即「 Tim

  • python中wheel的用法整理

    Python的第一个主流打包格式是.egg文件,现在大家庭中又有了一个叫做Wheel(*.whl)的新成员.wheel"被设计成包含PEP 376兼容安装(一种非常接近于磁盘上的格式)的所有文件".在本文中,我们将学习如何创建一个wheel以及如何在virtualenv中安装wheel. 起步 你需要pip来创建wheel,要学习安装pip,我强烈推荐阅读pip的安装页面 .如果你已经安装了pip,那么你需要把它升级到最新版本.你只需要做这些:在一个控制台窗口中,输入以下命令: pip

  • python中的编码知识整理汇总

    问题 在平时工作中,遇到了这样的错误: UnicodeDecodeError: 'ascii' codec can't decode byte 想必大家也都碰到过,很常见 .于是决定对python的编码做一个整理和学习. 基础知识 在python2.x中,有两种数据类型,unicode和str,这两个都是basestring的子类 >>> a = '中' >>> type(a) <type 'str'> >>> isinstance(a,b

  • Java与Python之间使用jython工具类实现数据交互

    最近有个功能需要java与python之间的数据交互,java需要把参数传给python,然后python计算的结果返回给java.于是就写了一个工具类. 首先,maven 需要加载jython的依赖.工具类代码如下: import java.util.List; import java.util.Map; import java.util.Properties; import org.apache.poi.ss.formula.functions.T; import org.python.co

  • python获取网络图片方法及整理过程详解

    这篇文章主要介绍了python获取网络图片方法及整理过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 方式1 使用urllib库 import urllib.request import os ,stat url = "https://cn.bing.com/th?id=OHR.Lidong2019_ZH-CN0761273672_1920x1080.jpg" try: urllib.request.urlretrieve(ur

  • python中元组的用法整理

    元组:tuple 内部只有两个可以操作的函数[count()/index()],一个是查看一个数据在元组中出现的总数另一个是查看. 一个数据在元组中的位置,外部有一个默认的函数sorted可以针对元组进行排序,排序注意:使用系统默认排序,但是必须保证排序的数据他们的数据类型是一致的!与元组查询相关函数,可以直接操作,如:len()查看元组中元素的个数. 声明元组方式 Name = tuple() name = ("1","2","3") name

  • Node.js 和 Python之间该选择哪个?

    最近,Node.js 和 Python 都因其广泛的特性和功能在市场上大受欢迎.在你开发Web应用程序的后端时,这两种技术都是你的首选. 众所周知,每个项目都有其自己的规范和需求,因此,选择一个合适的编程语言进行开发势在必行.在本文中,我们将会详细讨论这两种技术,列出其优缺点,并得出结论,希望能为你在项目选择哪种技术时提供一些帮助. 在开始对比这两种技术之前,让我们先来简单了解一下Node.js和Python的基础知识. 什么是Node.js? 用一种简单易懂的语言来说,Node.js是一个服务

  • Python脚本实现一键自动整理办公文件

    目录 导语: 1.准备 2.原理 3.自定义整理 导语: 举例:Python做一个根据后缀名整理文件的工具,先来看看效果: 自动整理前: 自动整理后: 这样看起来就好很多了. 1.准备 开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,可以访问这篇文章:python Windows最新版本安装教程 我们只需要修改源代码主程序中调用 auto_organize函数的参数即可完成对对应文件夹的整理,比如我想整理  C:\Users\83493\Downloads 文件夹: if

随机推荐