Perl 和 Python 都是开源的,但其哲学理念却刚好相反,因此常被人们将这两种语言放在一起进行比较。 本文将从 Perl 和 Python 的起源、基本数据类型、控制流、函数、包与模块、面向对象、正则表达式以及线程等方面进行比较。
Perl 是 Practical Extraction and Reporting Language的简称,起初是Larry为了格式化处理文本而创建的,作为一种“胶水型”语言,它具有强大的正则表达式和模式匹配功能以及灵活的数据结构,如动态数组、Hash 等,在语法规则上借鉴了 C/C++、Basic、Pascal 等语言,其不足之处在于存在一些冗余语法,代码的可读性较差。但Perl对字符、文本文件处理能力很强,以前要求shell+sed+awk+C才能完成的任务,只需perl脚本就可以完成了。Perl 作为一种自由而强大的编程语言,其中心思想是: There’s More Than One Way To Do It。(不只一种方法来做这件事 ),即「 Tim Toady 」。
Python 是一种基于面向对象的解释性交互式的开源编程语言,由CWI(阿姆斯特丹国家数学和计算机科学研究所)的研究员Guido van Rossum在1989年创立,Python 开发者的哲学是“用一种方法,最好是只有一种方法来做一件事”,Python 具有简单易学、代码规范、语法简单、可移植性强、支持多平台、类库丰富等优点。
Perl 支持的基本数据类型包括:标量、数组、哈希,在定义的时分别用 $、@、% 表示。
Python 支持五种基本数据类型:数字 (Numbers)、字符串 (String)、列表 (List)、元组 (Tuple) 和字典 (Dictionary)。
python的数字和字符串和 perl 中的标量对应,python的列表和perl的数组对应,python的元组可以看做是不可变的列表,python的字典和perl的hash对应。
Perl标量 $ | Python数字、字符串 |
---|---|
标量是Perl 中最简单的数据类型,大多数标量由数字或字符串组成。 数字类型有整数、浮点数等,字符串有单引号和双引号内两种形式,对长度没有限制。 单引号与双引号的区别为双引号内的字符串中出现的所有标量会被替换成该变量当前的值; 而单引号内的所有字符代表自己,比如\n不代表换行,而代表反斜线和 n 这两个字符 字符串的操作符有 . 拼接操作符和 x 重复操作符等。 |
Python 支持五种基本数字类型,分别为 int( 有符号整数 ) 、long( 长整数 ) 、bool( 布尔值 ) 、float( 浮点数 ) 、complex( 复数 ) 支持单引号和双引号字符串,但与 Perl 不同,转义字符在单引号中也会起作用。 字符串支持成员操作符 in,not in,连接操作符 + 以及重复操作符 * Python 字符串可以当做 list,支持切片操作符 [],[:] 和反向索引 |
Perl数组@ | Python列表 | |
---|---|---|
定义 | @shuzu=(1,5,'trek','amil'); |
list1=[1,5,'trek','amil'] |
字符串与数组/列表的互换 | $var_names = "google,taobao,runoob,weibo"; @names = split(',', $var_names); $string2 = join( ',', @names ); |
str= list('trek') #['t','r','e','k'] list3=' '.join(list2) |
索引 | 从0开始,索引-1为数组最后一个元素 | 从0开始,索引-1为最后一个元素 |
排序 | @shuzu1= sort {lc(a)cmplc(b)} @shuzu; #将每个元素转换为小写后再按字母顺排序;@shuzu1= sort {a<=>b} @shuzu; #对数字从小到大排序,调整a与b位置为从大到小排序;@shuzu = reverse(@shuzu); #逆序,不改变原列表 |
list1.reverse() #逆序,永久性排序;list1.sort() #按字母顺序永久性排序,无法恢复到原来的排序 |
计算 | $size_arr=@shuzu; #计算数组元素个数 |
len(list1) #计算列表元素个数min(numbers) #求最小值max(numbers) #求最大值sum(numbers) #求和 |
输出 | print($shuzu[0]); |
print(list1[0]) |
合并 | @numbers = (1,3,(4,5,6)); @arr0=(@shuzu,@shuzu0); |
|
末尾添加元素 | push(@shuzu,'tool') |
list1.append('tool') |
末尾删除元素 | $num=pop(@shuzu) |
name=list1.pop() |
删除指定的元素 | splice (@array, 2, 1);delete $array[2]; 删除索引2处的元素 |
name=list1.pop(2) 删除列表任意索引位置的元素,并让你能接着使用此元素; name=list1.remove(‘tool’) 删除列表中某个指定的元素(有重复元素的话只删除靠前的那个) list1[2:3]='' 将索引2处元素替换为空,后边的元素前移; del list1[2] 删除索引2处的元素 |
指定位置添加元素 | splice (@array, 1, 0, "Hello") 在1索引位置插入Hello,其他元素依次后移 |
str1[2:2] = "f" 索引2处添加 list1.insert(0,'tool') 列表索引0处插入元素 |
开头添加元素 | unshift(@shuzu,"f"); |
|
开头删除元素 | $num=shift(@shuzu); |
|
修改元素 | splice(@shuzu0, 5, 5, 21..25); 从数组索引值为5(即第6个元素)开始(包含替换的起始位置)替换5个元素,为21…25; |
str1=['a', 'b', 'f', 'd', 'e'];str1[2:4] = ["g","h","i"] 结果:[‘a’, ‘b’, “g”,“h”,“i”, ‘e’] str1 = ["a","b","c"];str1[2:] = list("de") 结果 : [‘a’, ‘b’, ‘d’, ‘e’] |
切片 | @shuzu2=@shuzu[2,4,6,7,-3,-1]; @shuzu3=@shuzu[2..-1]; 注意:左闭右闭 |
list2=list1[0:-3] 左闭右开 |
唯一元素数组 | set(list1) |
Perl哈希% | Python字典 |
---|---|
与 hash 相关的函数有: keys:返回 hash 的键列表 my @keylist = keys %hash value:返回值列表 my @valuelist = values %hash each:用两个元素的列表返回键值对。 while(($key,$value)= each %hash){print “$key=>$value\n”;} |
字典中的 key 是不能重复的,并且大小写敏感,同时字典中的元素是无序的。 字典也支持增删操作,往字典中添加元素 D[“age”]=23 , 删除元素 del D['name'] ;如果需要删除所有元素可以使用 D.clear() , 或者 del D 删除整个字典。 |
在控制结构方面,Perl 较 Python 丰富,除了支持传统的 if 、while 、for 控制结构,还支持 until 、unless 、foreach 等,Python 的控制结构相对要少一些,但已经能够满足语言的要求。
Perl 中没有 boolean 类型,数字 0、字符串 ‘0’ 、 “” 、空数组和 undef 为 False,其余表示 True,而 Python 中除了’’、""、0、()、[]、{}、None 为 False 之外,其他的都是 True。
1.Perl
if(条件判断){
}
if(条件判断){
}else{
}
if(条件判断){
}elsif(条件判断){
}else{
}
2.Python
if 条件判断:
执行语句1
执行语句2
if 条件判断:
执行语句
else:
执行语句
if 条件判断:
执行语句
elif 条件判断:
执行语句
else:
执行语句
1.Perl
for( $a = 0; $a < 10; $a = $a + 1 ){
print "a 的值为: $a\n";
}
foreach $i (@aList) {
stmt_1;
}
2.Python
for inter_var in iterable:
suite_to_repeat
else:
else_statement
1.Perl
while(expression) {
statement;
}
2.Python
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 语句不会执行任何操作。
1.Perl
sub functionName{
statement;
[return value]
}
2.Python
def functionName(arg1,arg2,[...]):
statement
[return value]
1.Perl
使用 return 语句显示返回;如果没有 return,默认返回最后一次运算的结果
2.Python
使用 return 语句显示返回,没有 return 语句,默认返回为 None。如果函数返回多个对象,python 把他们聚集起来并以一个元组返回。
1.Perl
& 函数名(参数 1,参数 2,...)
如果声明在前,可以省略 &
如果用户所定义的子过程与内置函数重名,则不能省略 &。
2.Python
函数名(参数 1,参数 2.....)
1.Perl
所有的参数都会自动存储为 @_ 中,其中第一个参数为 $[0], 第二个参数存储 $[1]。
传递引用,在参数前加入 \ 表示为引用
2.Python
Python 在传递参数的时候支持默认参数,规则是所有的未知参数必须出现在任何一个默认参数之前,如
def fun(arg1,defarg1=”var1”,defarg2=”12”)
变长参数:* 作为元组传递给函数。* *作为列表传递给函数。
1.Perl
Perl 模块有两种来源,一种是随 Perl 发行版本一同打包的,另外就是用 CPAN 中下载的。Perl 模块和包的概念并不清晰,两者有时可以混用。
Perl导入模块关键字 use;如:use ModuleName;
2.Python
一个 .py 文件就是一个 python 模块,把一堆相关的 python 模块放在一个目录下,再加上一个 init.py 文件就构成了一个 python 包。
import module 会导入 module 这个模块里的所有标识,但是这些标识现在都在 module 名字空间下。from module import * 也会导入 module 中所有标识,但是标识放到在当前名字空间里。
对象是对客观事物的抽象,类是对对象的抽象
对象是类的实例,类是对象的模板
1.Perl
Perl中的类即一个包或模块,这个包/模块包含相应的方法去创建和操作对象;
Perl中的对象即类中数据项的应用,这个应用知道该数据类型所属的类。
package Person;
sub new { #对象的构造函数
my $class = shift();
my $self = {
_firstName=>shift,
_lastName=>shift,
_ssn=>shift,
};
print("First Name is $self->{_firstName}\n");
print("Last Name is $self->{_lastName}\n");
print("SSN is $self->{_ssn}\n");
bless $self, $class;
return $self;
}
sub setFirstName{
my($self,$firstName)=@_;
$self->{_firstName}=$firstName if defined($firstName);
return $self->{_firstName};
}
1;
use strict;
use Person;
my $object = new Person( "mohand", "sam", 345);
##创建一个对象
##调用类的方法
$object->setFirstName("Mohd.");
package Employee;
use Person;
use strict;
our @ISA = qw(Person); # Perl 通过数组 @ISA 支持继承。
2.Python
#类的定义
class people:
name=''
age=0
__weight=0
def __init__(self,n,a,w):
self.name=n
self.age=a
self.__weight=w
def speak(self):
print("%s 说:我 %d 岁。" %(self.name,self.age))
##继承
class student(people):
grade=''
def __init__(self,n,a,w,g):
people.__init__(self,n,a,w)
self.grade=g
##覆写父类的方法
def speak(self):
print("%s 说:我 %d 岁了,我在读 %d 年级。" %(self.name,self.age,self.grade))
s = student('ken',10,60,3) #实例化类
s.speak()
python通过加载re模块来实现模式匹配的查找和替换,而Perl内置就有模式匹配功能。
threads模块提供了创建线程的工具,
create/async
。
#!/usr/bin/perl
use threads;
my $Param3='foo';
my $thr1=threads->create(\&sub1,'Param 1','Param 2',$Param3);
my @ParamList=(42,'Hello',3.14);
my $thr2=threads->create(\&sub1,@ParamList);
my $thr3=threads->create(\&sub1,qw(Param1 Param2 Param3));
sub sub1{
my @In=@_;
print("In the thread\n");
print('Got parameters >',join('<>',@In),"<\n");
}
Python中常用线程模块: _thread、threading(推荐使用)
Python中使用线程有两种方式:函数或者用类来包装线程对象。
1.函数式
调用
_thread
模块中的start_new_thread()
函数来产生新线程。
2.继承创建一个新的子类
直接从
threading.Thread
继承创建一个新的子类,并实例化后调用start()
方法启动新线程。