本章將對 Python 的主要特性作一個快速介紹,這樣你就能夠藉助之前的編程經驗識別出熟悉的語言結構,並馬上將 Python 付諸使用。雖然細節內容會在後續的章節中逐一講解,可是對總體的瞭解可讓你迅速融入到 Python 中。在Python解釋器全部的交互示例中, 你會看到 Python 的主提示符( >>> )和次提示符( ... )。主提示符是解釋器告訴你它在等待你輸入下一個語句,次提示符告訴你解釋器正在等待你輸入當前語句的其它部分。Python 有兩種主要的方式來完成你的要求:語句和表達式(函數、算術表達式等)。語句使用關鍵字來組成命令,相似告訴解釋器一個命令。你告訴 Python 作什麼,它就爲你作什麼,語句能夠有輸出,也能夠沒有輸出。表達式沒有關鍵字,它們能夠是使用數學運算符構成的算術表達式,也能夠是使用括號調用的函數。它們能夠接受用戶輸入,也能夠不接受用戶輸入,有些會有輸出,有些則沒有。(在 Python 中未指定返回值的函數會自動返回 None, 等價於 NULL) python
有些語言, 好比 C, 經過函數輸出數據到屏幕,例如函數 printf()。然而在 Python 和大多數解釋執行的腳本語言,使用語句進行輸出。不少的 shell 腳本語言使用 echo 命令來輸出程序結果。 程序員
核心筆記:在交互式解釋器中顯示變量的值一般當你想看變量內容時,你會在代碼中使用 print 語句輸出。不過在交互式解釋器中, 你能夠用 print 語句顯示變量的字符串表示,或者僅使用變量名查看該變量的原始值。 shell
>>> myString = 'Hello World!' express
>>> print myString 編程
Hello World! 數組
>>> myString app
'Hello World!' 函數
注意:在僅用變量名時,輸出的字符串是被用單引號括起來了的。這是爲了讓非字符串對象也能以字符串的方式顯示在屏幕上--即它顯示的是該對象的字符串表示,而不只僅是字符串自己。引號表示你剛剛輸入的變量的值是一個字符串。等你對 Python 有了較深刻的瞭解以後, 你就知道 print 語句調用 str()函數顯示對象, 而交互式解釋器則調用repr()函數來顯示對象。 佈局
下劃線(_)在解釋器中有特別的含義, 表示最後一個表達式的值。因此上面的代碼執行以後,下劃線變量會包含字符串: 學習
>>> _
'Hello World!'
Python 的 print 語句,與字符串格式運算符( % )結合使用,可實現字符串替換功能,這一點和 C 語言中的 printf()函數很是類似:
>>> print "%s is number %d!" % ("Python", 1)
Python is number 1!
%s 表示由一個字符串來替換, 而%d 表示由一個整數來替換, 另一個很經常使用的就是%f, 它表示由一個浮點數來替換。
Python 很是靈活,因此即便你將數字傳遞給 %s,也不會像其餘要求嚴格的語言同樣引起嚴重後果。
Print 語句也支持將輸出重定向到文件。這個特性是從Python2.0 開始新增的。符號 >> 用來重定向輸出,下面這個例子將輸出重定向到標準錯誤輸出:
import sys
print >> sys.stderr, 'Fatal error: invalid input!'
import sys
print >> sys.stderr, 'Fatal error: invalid input!
下面是一個將輸出重定向到日誌文件的例子:
logfile = open('/tmp/mylog.txt', 'a')
print >> logfile, 'Fatal error: invalid input!'
logfile.close()
從用戶那裏獲得數據輸入的最容易的方法是使用 raw_input()內建函數。它讀取標準輸入, 並將讀取到的數據賦值給指定的變量。你可使用 int() 內建函數將用戶輸入的字符串轉換爲整數。
>>> user = raw_input('Enter login name: ')
Enter login name: root
>>> print 'Your login is:', user
Your login is: root
上面這個例子只能用於文本輸入。下面是輸入一個數值字符串(並將字符串轉換爲整數) 的例子:
>>> num = raw_input('Now enter a number: ')
Now enter a number: 1024
>>> print 'Doubling your number: %d' % (int(num) * 2)
Doubling your number: 2048
內建函數 int()將數值字符串轉換成整數值,這樣才能夠對它進行數學運算。
核心筆記:從交互式解釋器中得到幫助在學習 Python 的過程當中, 若是須要獲得一個生疏函數的幫助, 只須要對它調用內建函數help()。經過用函數名做爲 help()的參數就能獲得相應的幫助信息:
>>> help(raw_input)
Help on built-in function raw_input in module __builtin__:
raw_input(...)
raw_input([prompt]) -> string
Read a string from standard input. The trailing newline is stripped.
If the user hits EOF (Unix: Ctl-D, Windows: Ctl-Z+Return), raise EOFError.
On Unix, GNU readline is used if enabled. The prompt string, if given, is printed without a trailing newline before reading.
核心風格: 保持在函數外作用戶交互操做
和大部分腳本及 Unix-shell 語言同樣,Python 也使用 # 符號標示註釋,從 # 開始,直到一行結束的內容都是註釋。
>>> # one comment
... print 'Hello World!' # another comment
Hello World!
有一種叫作文檔字符串的特別註釋。你能夠在模塊、類或者函數的起始添加一個字符串, 起到在線文檔的功能,這是 Java 程序員很是熟悉的一個特性。
def foo():
"This is a doc string."
return True
和其餘絕大多數的語言同樣,Python 中的標準算術運算符以你熟悉的方式工做,加、減、乘、除和取餘都是標準運算符。Python 有兩種除法運算符, 單斜槓用做傳統除法, 雙斜槓用做浮點除法(對結果進行四捨五入)。傳統除法是指若是兩個操做數都是整數的話, 它將執行是地板除(取比商小的最大整數),而浮點除法是真正的除法,無論操做數是什麼類型,浮點除法老是執行真正的除法。
還有一個乘方運算符, 雙星號(**):
>>> print -2 * 4 + 3 ** 2
1
就象你看到的, 運算符的優先級和你想象的同樣: + 和 - 優先級最低, *, /, //, %優先級較高, 單目運算符 + 和 - 優先級更高, 乘方的優先級最高。(3 ** 2) 首先求值, 而後是 (-2 * 4), 而後是對兩個結果進行求和。
Python 目前支持兩種「不等於」比較運算符, != 和 <> , 分別是 C 風格和 ABC/Pascal風格。目先後者慢慢地被淘汰了, 因此咱們推薦使用前者。
Python 也提供了邏輯運算符:and or not
Python 是動態類型語言, 也就是說不須要預先聲明變量的類型。變量的類型和值在賦值那一刻被初始化。變量賦值經過等號來執行。
Python 也支持增量賦值,也就是運算符和等號合併在一塊兒, 看下面的例子: n *= 10
Python 不支持 C 語言中的自增 1 和自減 1 運算符, 這是由於 + 和 - 也是單目運算符,Python 會將 --n 解釋爲-(-n) 從而獲得 n , 一樣 ++n 的結果也是 n.
Python支持五種基本數字類型:
int (有符號整數)
long (長整數)
bool (布爾值)
float (浮點值)
complex (複數)
Python 中有兩種有趣的類型是 Python 的長整型和複數類型。請不要將 Python 的長整數與 C 語言的長整數混淆。Python 的長整數所能表達的範圍遠遠超過 C 語言的長整數,事實上,Python 長整數僅受限於用戶計算機的虛擬內存總數。若是你熟悉 Java, Python 的長整數相似於 Java 中的 BigInteger 類型。
布爾值是特殊的整數。 儘管布爾值由常量 True 和 False 來表示, 若是將布爾值放到一個數值上下文環境中(比方將 True 與一個數字相加), True 會被當成整數值 1, 而 False則會被當成整數值 0。複數(包括-1 的平方根, 即所謂的虛數)在其它語言中一般不被直接支持(通常經過類來實現)。
其實還有第六種數字類型, decimal, 用於十進制浮點數。不過它並非內建類型, 你必須先導入 decimal 模塊纔可使用這種數值類型。因爲需求日漸強烈, Python 2.4 增長了這種類型。舉例來講, 因爲在二進制表示中有一個無限循環片斷,數字 1.1 沒法用二進制浮點數精確表示。所以, 數字 1.1 實際上會被表示成:
>>> 1.1
1.1000000000000001
>>> print decimal.Decimal('1.1')
1.1
Python 中字符串被定義爲引號之間的字符集合。Python 支持使用成對的單引號或雙引號,三引號(三個連續的單引號或者雙引號)能夠用來包含特殊字符。使用索引運算符( [ ] )和切片運算符( [ : ] )能夠獲得子字符串。字符串有其特有的索引規則:第一個字符的索引是 0,最後一個字符的索引是 -1。
加號( + )用於字符串鏈接運算,星號( * )則用於字符串重複。
能夠將列表和元組當成普通的「數組」,它能保存任意數量任意類型的 Python 對象。和數組同樣,經過從 0 開始的數字索引訪問元素,可是列表和元組能夠存儲不一樣類型的對象。
列表和元組有幾處重要的區別。列表元素用中括號( [ ])包裹,元素的個數及元素的值能夠改變。元組元素用小括號(( ))包裹,不能夠更改(儘管他們的內容能夠)。元組能夠當作是隻讀的列表。經過切片運算( [ ] 和 [ : ] )能夠獲得子集,這一點與字符串的使用方法同樣。
字典是 Python 中的映射數據類型,幾乎全部類型的 Python 對象均可以用做鍵,不過通常仍是以數字或者字符串最爲經常使用。
值能夠是任意類型的 Python 對象,字典元素用大括號({ })包裹。
代碼塊經過縮進對齊表達代碼邏輯而不是使用大括號,由於沒有了額外的字符,程序的可讀性更高。並且縮進徹底可以清楚地表達一個語句屬於哪一個代碼塊。固然,代碼塊也能夠只有一個語句組成。
標準 if 條件語句的語法以下:
if expression:
if_suite
若是條件表達式的值非 0 或者爲布爾值 True, 則代碼組 if_suite 被執行; 不然就去執行下一條語句。代碼組是一個Python術語, 它由一條或多條語句組成,表示一個子代碼塊。Pthon與其它語言不一樣, 條件表達式並不須要用括號括起來。
if x < .0:
print '」x」 must be atleast 0!'
Python 固然也支持 else 語句, 語法以下:
if expression:
if_suite
else:
else_suite
Python 還支持 elif (意指 「else-if 」)語句,語法以下:
if expression1:
if_suite
elif expression2:
elif_suite
else:
else_suite
標準 while 條件循環語句的語法相似 if. 再說一次, 要使用縮進來分隔每一個子代碼塊。
Python 中的 for 循環與傳統的 for 循環(計數器循環)不太同樣, 它更象 shell 腳本里的foreach 迭代。Python 中的 for 接受可迭代對象(例如序列或迭代器)做爲其參數,每次迭代其中一個元素。
>>> print 'I like to use the Internet for:'
I like to use the Internet for:
>>> for item in ['e-mail', 'net-surfing', 'homework','chat']:
... print item
...
net-surfing
homework
chat
上面例子的輸出若是能在同一行就會美觀許多。print 語句默認會給每一行添加一個換行符。只要在 print 語句的最後添加一個逗號(,), 就能夠改變它這種行爲。
print 'I like to use the Internet for:'
for item in ['e-mail', 'net-surfing', 'homework', 'chat']:
print item,
上面的代碼還添加了一個額外的沒有任何參數的 print 語句, 它用來輸出一個換行符。不然, 提示信息就會馬上出如今咱們的輸出以後。下面是以上代碼的輸出:
I like to use the Internet for:
e-mail net-surfing homework chat
爲了輸出清晰美觀, 帶逗號的 print 語句輸出的元素之間會自動添加一個空格。經過指定輸出格式, 程序員能夠最大程度的控制輸出佈局, 也不用擔憂這些自動添加的空格。它也能夠將全部數據放到一處輸出—只須要將數據放在格式化運算符右側的元組或字典中。
對字符串來講, 很容易迭代每個字符:
>>> foo = 'abc'
>>> for c in foo:
...
print c
...
a
b
c
range()函數常常和 len()函數一塊兒用於字符串索引。在這裏咱們要顯示每個元素及其索引值:
>>> foo = 'abc'
>>> for i in range(len(foo)):
... print foo[i], '(%d)' % i
...
a (0)
b (1)
c (2)
不過, 這些循環有一個約束, 你要麼循環索引, 要麼循環元素。這致使了 enumerate()函數的推出(Python2.3 新增)。它同時作到了這兩點:
>>> for i, ch in enumerate(foo):
... print ch, '(%d)' % i
...
a (0)
b (1)
c (2)
這是一個讓人欣喜的術語, 表示你能夠在一行中使用一個 for 循環將全部值放到一個列表
當中:
>>> squared = [x ** 2 for x in range(4)]
>>> for i in squared:
... print i
0
1
4
9
列表解析甚至能作更復雜的事情, 好比挑選出符合要求的值放入列表:
>>> sqdEvens = [x ** 2 for x in range(8) if not x % 2]
>>>
>>> for i in sqdEvens:
... print i
0
4
16
36
如何打開文件:
handle = open(file_name, access_mode = 'r')
file_name 變量包含咱們但願打開的文件的字符串名字, access_mode 中 'r' 表示讀取,'w' 表示寫入, 'a' 表示添加。其它可能用到的標聲還有 '+' 表示讀寫, 'b'表示二進制訪問. 若是未提供 access_mode , 默認值爲 'r'。若是 open() 成功, 一個文件對象句柄會被返回。全部後續的文件操做都必須經過此文件句柄進行。當一個文件對象返回以後, 咱們就能夠訪問它的一些方法, 好比 readlines() 和 close()。
下面有一些代碼, 提示用戶輸入文件名, 而後打開一個文件, 並顯示它的內容到屏幕上:
filename = raw_input('Enter file name: ')
fobj = open(filename, 'r')
for eachLine in fobj:
print eachLine,
fobj.close()
代碼中另外一個有趣的語句是咱們又一次在 print 語句中使用逗號來抑制自動生成的換行符號。爲何要這樣作?由於文件中的每行文本已經自帶了換行字符, 若是咱們不抑制 print語句產生的換行符號, 文本在顯示時就會有額外的空行產生。
file()內建函數是最近才添加到 Python 當中的。它的功能等同於 open(), 不過 file()這個名字能夠更確切的代表它是一個工廠函數。(生成文件對象)相似 int()生成整數對象,dict()生成字典對象。
編譯時會檢查語法錯誤, 不過 Python 也容許在程序運行時檢測錯誤。當檢測到一個錯誤,Python 解釋器就引起一個異常, 並顯示異常的詳細信息。程序員能夠根據這些信息迅速定位問題並進行調試, 並找出處理錯誤的辦法。
要給你的代碼添加錯誤檢測及異常處理, 只要將它們封裝在 try-except 語句當中。 try以後的代碼組, 就是你打算管理的代碼。 except 以後的代碼組, 則是你處理錯誤的代碼。
try:
filename = raw_input('Enter file name: ')
fobj = open(filename, 'r')
for eachLine in fobj:
print eachLine,
fobj.close()
except IOError, e:
print 'file open error:', e
程序員也能夠經過使用 raise 語句故意引起一個異常。
相似其它的語言, Python 中的函數使用小括號( () )調用。函數在調用以前必須先定義。若是函數中沒有 return 語句, 就會自動返回 None 對象。
Python 是經過引用調用的。這意味着函數內對參數的改變會影響到原始對象。不過事實上只有可變對象會受此影響, 對不可變對象來講, 它的行爲相似按值調用。
下面是一個簡短的例子:
def addMe2Me(x):
'apply + operation to argument'
return (x + x)
這個函數, 乾的是「在個人值上加我」的活。它接受一個對象, 將它的值加到自身, 而後返回和。對於數值類型參數, 它的結果是顯而易見的, 不過我要在這裏指出, 加號運算符幾乎與全部數據類型工做。換句話說, 幾乎全部的標準數據類型都支持 + 運算符, 無論是數值相加仍是序列合併。
函數的參數能夠有一個默認值, 若是提供有默認值,在函數定義中, 參數以賦值語句的形式提供。事實上這僅僅是提供默認參數的語法,它表示函數調用時若是沒有提供這個參數, 它就取這個值作爲默認值。
類是面向對象編程的核心, 它扮演相關數據及邏輯的容器角色。它們提供了建立「真實」對象(也就是實例)的藍圖。由於 Python 並不強求你以面向對象的方式編程(與 Java 不一樣),此刻你也能夠不學習類。
如何定義類
class ClassName(base_class[es]):
"optional documentation string"
static_member_declarations
method_declarations
使用 class 關鍵字定義類。能夠提供一個可選的父類或者說基類; 若是沒有合適的基類,那就使用 object 做爲基類。class 行以後是可選的文檔字符串, 靜態成員定義, 及方法定義。
class FooClass(object):
"""my very first class: FooClass"""
version = 0.1 # class (data) attribute
def __init__(self, nm='John Doe'):
"""constructor"""
self.name = nm # class instance (data) attribute
print 'Created a class instance for', nm
def showname(self):
"""display instance attribute and class name"""
print 'Your name is', self.name
print 'My name is', self.__class__.__name__
def showver(self):
"""display class(static) attribute"""
print self.version
# references FooClass.version
def addMe2Me(self, x): # does not use 'self'
"""apply + operation to argument"""
return x + x
在上面這個類中, 咱們定義了一個靜態變量 version, 它將被全部實例及四個方法共享,__init__(), showname(), showver(), 及熟悉的 addMe2Me(). 這些 show*()方法並無作什麼有用的事情, 僅僅輸出對應的信息。 __init__() 方法有一個特殊名字, 全部名字開始和結束都有兩個下劃線的方法都是特殊方法。
當一個類實例被建立時, __init__() 方法會自動執行, 在類實例建立完畢後執行, 相似構建函數。__init__() 能夠被當成構建函數, 不過不象其它語言中的構建函數, 它並不建立實例--它僅僅是你的對象建立後執行的第一個方法。它的目的是執行一些該對象的必要的初始化工做。經過建立本身的 __init__() 方法, 你能夠覆蓋默認的 __init__()方法(默認的方法什麼也不作),從而可以修飾剛剛建立的對象。在這個例子裏, 咱們初始化了一個名爲 name的類實例屬性(或者說成員)。這個變量僅在類實例中存在, 它並非實際類自己的一部分。__init__()須要一個默認的參數, 前一節中曾經介紹過。毫無疑問,你也注意到每一個方法都有的一個參數, self.
什麼是 self ? 它是類實例自身的引用。其餘語言一般使用一個名爲 this 的標識符。
如何建立類實例
>>> foo1 = FooClass()
Created a class instance for John Doe
屏幕上顯示的字符串正是自動調用 __init__() 方法的結果。當一個實例被建立,__init__()就會被自動調用。無論這個__int__()是自定義的仍是默認的。
建立一個類實例就像調用一個函數, 它們確實擁有同樣的語法。它們都是可調用對象。類實例使用一樣的函數運算符調用一個函數或方法。既然咱們成功建立了第一個類實例, 那如今來進行一些方法調用:
>>> foo1.showname() Your name is John Doe
My name is __main__.FooClass
>>> foo1.showver()
0.1
>>> print foo1.addMe2Me(5)
10
每一個方法的調用都返回咱們指望的結果。比較有趣的數據是類名字。在 showname()方法中,咱們顯示 self.__class__.__name__ 變量的值。對一個實例來講, 這個變量表示實例化它的類的名字。(self.__class__引用實際的類)。在咱們的例子裏, 建立類實例時咱們並未傳遞名字參數, 所以默認參數 'John Doe' 就被自動使用。
模塊是一種組織形式, 它將彼此有關係的 Python 代碼組織到一個個獨立文件當中。模塊能夠包含可執行代碼, 函數和類或者這些東西的組合。當你建立了一個 Python 源文件,模塊的名字就是不帶 .py 後綴的文件名。一個模塊建立以後, 你能夠從另外一個模塊中使用 import 語句導入這個模塊來使用。
如何導入模塊
import module_name
如何訪問一個模塊函數或訪問一個模塊變量
一旦導入完成, 一個模塊的屬性(函數和變量)能夠經過熟悉的 .句點屬性標識法訪問。
module.function()
module.variable
>>> import sys
>>> sys.stdout.write('Hello World!\n')
Hello World!
>>> sys.platform
'win32'
>>> sys.version
'2.4.2 (#67, Sep 28 2005, 10:51:12) [MSC v.1310 32 bit (Intel)]'
這些代碼的輸出與咱們使用 print 語句徹底相同。惟一的區別在於此次調用了標準輸出的write()方法,並且此次須要顯式的在字符串中提供換行字符, 不一樣於 print 語句, write()不會自動在字符串後面添加換行符號。
核心筆記:什麼是「PEP」?
一個 PEP 就是一個 Python 加強提案(Python Enhancement Proposal), 這也是在新版 Python 中增長新特性的方式。從初學者的角度看,它們是一些高級讀物, 它們不但提供了新特性的完整描述, 還有添加這些新特性的理由, 若是須要的話, 還會提供新的語法、技術實現細節、向後兼容信息等等。在一個新特性被整合進 Python 以前,必須經過 Python 開發社區,PEP 做者及實現者,還有 Python 的創始人,Guido van Rossum(Python 終身的仁慈的獨裁者)的一致贊成。PEP1 闡述了 PEP 的目標及書寫指南。在 PEP0 中能夠找到全部的 PEP。
PEP 索引的網址是: http://python.org/dev/peps
dir([obj]) 顯示對象的屬性名,若是沒有提供參數, 則顯示全局變量的名字。
help([obj]) 以一種整齊美觀的形式顯示對象的文檔字符串, 若是沒有提供任何參數, 則會進入交互式幫助。
int(obj) 將一個對象轉換爲整數
len(obj) 返回對象的長度
open(fn, mode) 以mode('r' = 讀, 'w'= 寫)方式打開一個文件名爲 fn 的文件
range([[start,]stop[,step]) 返回一個整數列表。起始值爲 start, 結束值爲 stop - 1; start默認值爲 0, step默認值爲1。
raw_input(str) 等待用戶輸入一個字符串, 能夠提供一個可選的參數 str 用做提示信息。
str(obj) 將一個對象轉換爲字符串
type(obj) 返回對象的類型(返回值自己是一個type對象)