關于 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 |
定義 |
- 基本語法:
sub functionName{ statement; [return value] } |
- 基本語法:
def functionName(arg1,arg2,[...]): statement [return value]
- 內嵌函數:
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,參數 2.....)
- 函數名(參數名 1= 值,參數名 2= 值 .......)
|
函數參數 |
- 在子程序調用的后面加上被括號圈引的列表表達式即可,所有的參數都會自動存儲為 @_ 中,其中第一個參數為 $_[0], 第二個參數存儲 $_[1]。
- 傳遞引用,在參數前加入 \ 表示為引用
|
- 按照參數聲明的關鍵字順序直接傳遞;
- 通過關鍵字參數 testFun(par1=“2”,par2=“45”)
- 默認參數:
> Python 在傳遞參數的時候支持默認參數,規則是所有的位置參數必須出現在任何一個默認參數之前,如 def fun(arg1,defarg1=”var1”,defarg2=”12”), 如果在調用的時候沒有給出參數值,則會使用默認值
- 變長參數:
一種方法是利用非關鍵字可變長參數 , 可變長的參數元組必須在位置和默認參數之后 , 帶元組的函數語法如下: 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 cnt10:
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 的起源,基本數據類型、控制結構、函數、包與模塊、面向對象、正則表達式以及線程等方面進行了比較,從而給需要同時掌握這兩種腳本語言的開發人員一定參考,以便更好的理解與應用。
參考資料 學習
- 在 developerWorks Linux 專區尋找為 Linux 開發人員(包括 Linux 新手入門)準備的更多參考資料,查閱我們 最受歡迎的文章和教程。
- 在 developerWorks 上查閱所有 Linux 技巧和 Linux 教程。
- 隨時關注 developerWorks 技術活動和 網絡廣播。
- 參考 Tutorial Perl官方文檔關注更多 Perl 動態。
- 參考 Perl Document了解 Perl 基本語法。
- 參考 Tutorial Python查看 Python 的官方文檔。
您可能感興趣的文章:- Python Mysql數據庫操作 Perl操作Mysql數據庫
- 利用perl、python、php、shell、sed、awk、c 實現字符串的翻轉
- Python和perl實現批量對目錄下電子書文件重命名的代碼分享
- 用Python制作在地圖上模擬瘟疫擴散的Gif圖
- Shell、Perl、Python、PHP訪問 MySQL 數據庫代碼實例
- Python和Perl繪制中國北京跑步地圖的方法