Python是一門腳本語言,我也久聞大名,但正真系統的接觸學習是在去年(2013)年底到今年(2014)年初的時候。不得不說的是Python的官方文檔相當齊全,如果你是在Windows上學習Python,安裝包自帶的“Python Manuals”就是一份很好的學習資料(基本上不用去找其他資料了);尤其是其中的Tutorial,非常適合初學者。本文一方面總結了python語言的核心——數據類型和控制結構;另一方面,通過與其他語言的對比表達了我對Python的一些拙見。
數據類型
Python簡潔的背后是因為有着強大的類型系統的支持。Python世界的基本數據類型有{int, long, float, complex, str, list, set, tuple, dict},下面通過Python解釋器在交互模式下的輸入輸出實例進行演示(其中有前導符>>>或...的是輸入):
tips: Python世界里,可以用type(x)來輸出x的類型.
int, long, float, str, complex
>>> type(123) <type 'int'> >>> type(-234) <type 'int'> >>> type(123456123456) <type 'long'> >>> type(-123456123456) <type 'long'> >>> type(123.456) <type 'float'> >>> type('abc') <type 'str'> >>> type("hello, world") <type 'str'>
從最后兩次輸入可以看到Python的字符串可以用單引號也可以用雙引號。另外,大家可能會疑惑的是到底多大是int和多大是long呢?下面我們來一探究竟:
>>> type(123456) <type 'int'> >>> type(123456789) <type 'int'> >>> type(1234567890) <type 'int'> >>> type(12345678901) <type 'long'>可以看到1234567890還是int,12345678901就是long了,說明int是有范圍的。記得C/C++的int長度(4B)的同學都知道,C/C++里int的取值范圍是:[-2^31, 2^31-1]也就是[-2147483648, 2147483647]。據此,我們可以看看Python的int范圍:
>>> type(2147483647) <type 'int'> >>> type(2147483648) <type 'long'> >>> type(-2147483648) <type 'int'> >>> type(-2147483649) <type 'long'>這次試驗說明,Python的int范圍和C/C++一樣。(事實上和long一樣,這里只是因為運行的是32位的python解釋器,如果是64位python解釋器,int是8字節)
那么,如果我想指定一個比較小的long怎么辦呢?可以通過加L(或小寫l)后綴:
>>> type(1L) <type 'long'> >>> type(2l) <type 'long'>
另外,Python的浮點數是沒有double的:
>>> type(123.456) <type 'float'> >>> type(123456123456.123456123456123456123456) <type 'float'>
復數類型在很多語言中是沒有的,Python通過整數加J(或小寫j)后綴表示復數:
>>> type(3+4j) <type 'complex'> >>> type(3+4J) <type 'complex'> >>> type(4j) <type 'complex'> >>> type(j) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'j' is not defined >>> type(1j) <type 'complex'>但是1j不允許直接寫成j,j會被當做name查找,如果沒找到就會報錯。
tuple, list, set, dict
tuple, list, set, dict分別是元組、列表、集合、字典(有的語言叫映射map)。這些類型才是Python類型系統的過人之處,在多數編譯型語言(C、C++、Java、C#等)中,這些類型都要通過庫來提供(如C++、Java、C#),有的或許庫也沒有提供(如C)。
>>> type([1, 2, 3]) <type 'list'> >>> type({2, 3, 4}) <type 'set'> >>> type((3, 4, 5)) <type 'tuple'> >>> type({'key1': 'value1', 'key2': 'value2'}) <type 'dict'>可以看到 (), [], {}和它括起來的一系列元素,分別是表示:元組、列表、集合。而dict則是{key1: value1, [key2: value2, ...]}的形式。
上面列出的各種集合的元素類型一致,這在編譯型語言里通常是必須的,但在Python里不必:
>>> (1, 'two', 3.0) (1, 'two', 3.0) >>> [(1, 'two', 3.0), '4', 5] [(1, 'two', 3.0), '4', 5] >>> {1, 2L, 3.0, 4j} set([1, 2L, 3.0, 4j]) >>> {1: 'one', 'one': 1} {1: 'one', 'one': 1}
控制結構
結構化程序設計方法提出之時,就有前輩證明了任何算法都可以使用:順序、選擇、循環三種結構表達。下面將展示Python的基本語法,以及選擇和循環。
順序結構
順序結構本身沒什么好說的,這里介紹一下Python的其他特性。
語句
Python的語句以換行符結尾(不像C家族的分號結尾):
>>> print "hello, world" hello, world並且Python程序沒有所謂的“入口”,這和多數腳本語言類似。
弱類型
Python是弱類型的,也就是變量的類型不是一成不變的。這也和很多腳本語言類似。
>>> a = 123 >>> b = "asdf" >>> c = [3, 4, 5] >>> a 123 >>> b 'asdf' >>> c [3, 4, 5] >>> a = b >>> b 'asdf'
這段交互中有兩點與C語言(C++等)不同:
- 使用變量前不用向提前聲明變量的類型
- 一個變量初始化為一個類型后還能給他賦其他類型的值
提示:在Python解釋器的交互模式下直接輸入變量名也能顯示變量的值
“變量”一詞在Python里應該叫“名字”(或者符號)更確切,在Python中你可以給一個符號賦予任何類型的值。稍后你將會看到可以給原本賦值為int的對象賦值為一個函數,一個類。
函數
Python的函數定義以def開始,如果有返回值需要用return傳遞返回值。
比如如下代碼定義了一個名為sayHello的函數,並用'Jack'為參數進行了一次調用:
def sayHello(name): print 'Hello, ' + name + '!' sayHello('Jack')這段代碼的運行結果為:Hello, Jack!
(可將這段代碼保存為sayHello.py,然后在對應目錄運行python sayHello.py)
類
Python的類定義以class開始,屬性可以在class下方聲明也可以在__init__方法里通過self.xxx隱式聲明。
先來一段最簡單的關於類的代碼:
class Man: def __init__(self, name): self.name = name def hello(self): print 'Hello, ' + self.name + '!' m = Man('Jack') m.hello()這段代碼也會輸出:Hello, Jack!
tips: Python方法的第一個參數必須是名為self的參數,用於操作對象的成員。__init__類似其他語言的”構造方法“。
類的更多特性和OOP有關,以后有時間再單獨發一篇博文展示。
類的更多特性和OOP有關,以后有時間再單獨發一篇博文展示。
順便看看函數、類以及類的實例在Python解釋器眼中都是什么:
>>> type(sayHello) <type 'function'> >>> type(Man) <type 'classobj'> >>> type(m) <type 'instance'> >>> type(m.hello) <type 'instancemethod'> >>> type(Man.hello) <type 'instancemethod'>可以想象,Python世界里的東西都是”灰色“的,解釋器對它們”一視同仁“,從來不以貌取人,只看他們現在身上的標簽是什么~
選擇結構
Python的選擇結構以if開始。
bool
if必然要涉及bool值,Python bool的取值為True和False:
>>> type(1==1) <type 'bool'> >>> type(True) <type 'bool'> >>> type(False) <type 'bool'>
(上面好像忘了列出bool類型)
>>> if 1: ... print "true" ... true >>> if 0: ... print "true" ... else: ... print "false" ... false >>> if 0.0: ... print "0.0 is true" ... >>> if 0j: ... print "0j is true" ...提示:Python是以代碼縮進區分代碼塊的
除此之外,空的string和空的集合(tuple, list, set)也是False:
>>> if '': ... print 'null string is true' ... >>> if (): ... print 'null tuple is true' ... >>> if []: ... print 'null list is true' ... >>> if {}: ... print 'null set is true' ...
if, if-else & if-elif-else
上面幾個if示例多是只有一個分支的,當然Python也支持多個分支的if:
>>> x = int(raw_input("Please enter an integer: ")) Please enter an integer: 42 >>> if x < 0: ... x = 0 ... print 'Negative changed to zero' ... elif x == 0: ... print 'Zero' ... elif x == 1: ... print 'Single' ... else: ... print 'More' ... More
循環結構
Python的循環有for和while兩種,沒有do-while,也沒有loop-until。
for
Python的for循環和C的不同,它更像C++,Java里的新式for循環:
>>> a = [1, 'two', 3.0] >>> for i in a: ... print i ... 1 two 3.0這種for迭代集合很方便。
但是要想像典型C語言的for循環那樣迭代一個整數區間怎么辦?別怕,Python提供了內置(built-in)函數range(),它能返回整數區間列表,供你迭代,用起來也很方便:
>>> for i in range(1, 6): ... print i ... 1 2 3 4 5 >>> for i in range(10, 65, 10): ... print i ... 10 20 30 40 50 60這里展示了range的兩種調用形式,一種是range(a, b),它將返回一個從a(包含a)到b(不包含)的整數列表(list),另一種range(a, b, s),將返回一個a~b,以s為步長的list:
>>> range(1, 6) [1, 2, 3, 4, 5] >>> range(10, 65, 10) [10, 20, 30, 40, 50, 60]
while
Python的while循環和C的while差不多:
>>> i = 1 >>> >>> while i < 5: ... i = i+1 ... print i ... 2 3 4 5
順便一提,Python里 i=i+1 不能寫成i++,Python不支持這種語法;但可以寫成 i += 1:
>>> i 5 >>> i += 1 >>> i 6 >>> i++ File "<stdin>", line 1 i++ ^ SyntaxError: invalid syntax >>> ++i 6 >>> i 6各位可能會疑惑,為什么++i可以?因為pyhon支持前置的+(正負號)運算,++被當做兩次正運算了;同理,+++i,++++i都是一樣的;我們可以順便測一下負號運算:
>>> i 6 >>> +++i 6 >>> ++++i 6 >>> -i -6 >>> --i 6 >>> ---i -6和想象的結果一致,Great!
輸入輸出(IO)
當你想動手寫點”更有意思“的小程序的時候,你會發現除了三大基本控制結構和數據類型之外,你最需要的可能就是IO功能。
Q: 輸出可以用print,那么輸入呢?是input嗎?
A:input可以,但更多時候需要用的可能是raw_input和readline這兩個built-in function,但readline僅適用於Unix平台.
Q:那么input和raw_input有什么區別呢?
A:來看看我和解釋器的下面這段交互,看看你能不能自己發現它們的不同。
>>> varA = raw_input('please input:') please input:Life is too short, you need Python! >>> varA 'Life is too short, you need Python!' >>> type(raw_input('input something:')) input something:asdf <type 'str'> >>> type(raw_input('input something:')) input something:123 <type 'str'>A:你看到了,raw_input不論你輸入什么都會返回str類型,這也是為什么叫做raw_input的原因。
A: 繼續往下,你會看到input:
>>> type(input('input sth:')) input sth:123 <type 'int'> >>> type(input('input sth:')) input sth:asdf Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<string>", line 1, in <module> NameError: name 'asdf' is not defined >>> type(input('input sth:')) input sth:varA <type 'str'> >>> input('sth:') sth:varA 'Life is too short, you need Python!' >>> input('try some input like your code:') try some input like your code:[1, 'two', 3.0] [1, 'two', 3.0] >>> input('try again:') try again:'Oh!!!' 'Oh!!!'