天天看點

Python基礎文法

基礎文法:如,變量的聲明與調用、基本輸出語句、代碼塊文法、注釋等;

資料類型:通常都為 數字、字元串、布爾值、數組、連結清單、Map、Set等;

運算符:算術運算符、指派運算符、比較運算符、邏輯運算符、位運算符等;

流程控制語句:分支語句、循環語句;

類的定義與使用:這個是面向對象程式設計語言才有的内容;

常用API的使用:常用方法、工具類或子產品的使用。

掌握上面的内容,就算是對一門程式設計語言入門了,剩下的就是不斷的在使用和總結中去提升了。本節我們先來說一說學習Python時的準備工作以及Python的基礎文法。

Hello, World!

Python2.x or Python3.x

變量與常量

接收使用者輸入

指定字元編碼與解釋器

注釋

導入子產品

擷取腳本傳入的參數

代碼塊文法

Python程式執行過程與.pyc檔案

在任意一個目錄下建立一個hello.py檔案,我們來輸出一個經典語句"Hello World!"

執行hello.py這個python腳本的方式是:

<code>python hello.py</code>

輸出為:

Hello, World

當然也可以直接進入python解釋器互動式終端去執行print("Hello, World"),如下圖所示:

Python基礎文法
思考:為什麼列印一句“Hello World”已經成為很多人學習一門新語言的第一句代碼? 有人說,這是學習一門語言入門的象征,因為寫完了這個我就可以對别人說“我會寫xx語言的程式了”。本人認為要了解為什麼Hello World如此簡單,卻又如此廣為人知并被傳頌,隻需要想清楚一個問題:這個程式帶給我們什麼? 它告訴我們在這個程式設計語言中基本的輸出語句是怎樣的,這很重要; 它告訴我們要怎樣去執行這個程式設計語言編寫的程式,這同樣很重要。 如果不知道上述兩個問題,我們将寸步難行。

我們分别使用Python2.7 和 Python3.5的解釋器提供的互動式終端來分别執行以下兩條指令:

Python基礎文法

通過上圖的執行結果會發現,<code>print "Hello, World"</code> 這條語句在Python2.7中可以正常執行,而在Python 3.5中會報錯,也就是說Python 3.x與Python 2.x是不相容的。這貌似是Python開發者犯的一個錯誤,而事實是Guido Van Rossum(Python語言的最初建立者)故意為之。Guido的本意就是想不考慮太多向後相容性的問題,去适當地清理一下Python 2.x中不合理的内容,而不是把Python 3.x簡單的當做對Python 2.x的更新版本。

實際上,Python 3.0在2008年12月就已經釋出了,Python官方在2010年年中釋出2.7時宣布,2.7将是Python 2.x的最後一個主釋出版本。其實Python 2.7 是向Python 3.x的一個過渡版本,裡面支援了一些Python 3.x的特性。

2014年11月,Python官方宣布Python 2.7将會被支援到2020年,并再次确認了不會有Python 2.8釋出,希望使用者盡快遷移到Python 3.4+ 。3.x正在處于積極開發狀态,并且在過去5年裡已經釋出了多個穩定版本,包括2012年的3.3,2014年的3.4,2015年的3.5。這意味着最近所有的标準庫更新将預設隻能在Python 3.x中可用。

在Python 3.x中,輸出語句需要使用print()函數,該函數接收一個關鍵字參數,以此來代替Python 2.x中的大部分特殊文法。下面是幾個對比項:

目标

Python 2.x的實作

Python 3.x的實作

拼接并輸出多個值

print "The result is", 2+3

print("The result is", 2+3)

列印一個元祖(1,2,3)

print(1,2,3) 或 print (1,2,3)

print((1,2,3))

輸出一個内容并且不換行

print “Hello”,

print("Hello", end=" ")

輸出一個新空白行

print

print()

将輸出内容輸出到标準錯誤輸出檔案

print &gt;&gt;sys.stderr, "fatal error"

print("fatal error", file=sys.stderr)

自定義多個輸出内容之間的分隔/拼接符

N/A

print("There are &lt;", 2**32, "&gt; possibilites!", sep="")

Python 2.x中使用的預設字元編碼為ASCII碼,要使用中文字元的話需要指定使用的字元編碼,如UTF-8;Python 3.x中使用的預設字元編碼為Unicode,就不存在這個問題了。

python 2.x中如果要給多個變量同時指派,要求=号右邊的表達式傳回結果的個數要與=号左邊接收值的變量個數相等,不能多,也不能少。如:

python 3.x中允許=号昨邊的變量數小于=号右邊表達式傳回的結果的個數,但是需要有1個且隻能有1個字典類型的變量來接收多餘的傳回值。與python 2.x相同的是 python 3.x中=号左邊的變量數也是不能多與=号右邊表達式的傳回值個數,但是錯誤提示語更清晰了。

Old Name

New Name

_winreg

winreg

ConfigParser

configparser

copy_reg

copyreg

Queue

queue

SocketServer

socketserver

markupbase

_markupbase

repr

reprlib

test.test_support

test.support

如果是要開發一個新項目,不用考慮與老項目的相容問題,最好是使用Python 3,因為就像Python官方說的那樣,Python 3才是Python語言的将來。現在很多第三方類庫已經完成了或者正在積極完成對Python 3的支援,隻是有些項目由于過于龐大,很難在短時間内完成。我們需要考慮的最大問題在于,新項目中是否存在必須的第三方類庫,且該類庫目前還不支援Python 3。如果不存在這個問題,那堅定的選擇Python 3吧。

這是隻是簡單說下Python中變量的定義和使用,友善繼續下面的内容。事實上,Python中變量的使用确實很簡單:

python定義變量無需指定變量類型,python解釋器會在運作時自動推斷變量的資料類型。我們可以通過type()方法來檢視變量類型:

Python基礎文法

事實上,Python中沒有文法限制下的常量,僅僅是用完全大寫字母的變量來表示這個變量不應該被改變。

很多時候都需要與使用者進行互動,通過使用者輸入的内容來做下一步操作。這裡需要說明的是,Python 2 與Python 3中接收使用者輸入的方法是不一樣的。

Python 2中接收使用者輸入時,主要使用的是raw_input()函數:

Python基礎文法

Python 3中接收使用者輸入時,主要使用的是input()函數:

Python基礎文法

通過Python 2中的raw_input() 與 Python 3中的input() 擷取到的值都是str類型,若想轉換為其他資料類型需要進行強制類型轉換,這個等将Python資料類型的時候會說。

Python基礎文法
Python基礎文法

Python 2中其實也有input()方法,但是通過這個input()方法擷取的值是與輸入内容的資料類型有關的,這很容易造成混亂,是以現在Python 2中很少用這個方法,而是用raw_input()代替了。

Python基礎文法

計算機隻認識0和1組成的二進制序列,是以任何檔案中的内容要想被計算機識别或者想存儲在計算機上都需要轉換為二進制序列。那麼字元與二進制序列怎麼進行想換轉換呢?于是人們嘗試建立一個表格來存儲一個字元與一個二進制序列的對應關系。

編碼 将字元轉換為對應的二進制序列的過程叫做字元編碼

解碼 将二進制序列轉換為對應的字元的過程叫做字元解碼

最早建立這個字元與十進制數字對應的關系的是美國,這張表被稱為ASCII碼(American Standard Code for Information Interface, 美國标準資訊交換代碼)。ASCII碼是基于拉丁字母的一套電腦程式設計系統,主要用于顯示現代英語和其他西歐語言。它被設計為用1個位元組來表示一個字元,是以ASCII碼表最多隻能表示2**8=256個字元。實際上ASCII碼表中隻有128個字元,剩餘的128個字元是預留擴充用的。

Python基礎文法

随着計算機的普及和發展,很過國家都開始使用計算機。大家發現ASCII碼預留的128個位置根本無法存儲自己國家的文字和字元,是以各個國家開始制定各自的字元編碼表,其中中國的的字元編碼表有GB2312和GBK。

後來随着世界網際網路的形成和發展,各國的人們開始有了互相交流的需要。但是這個時候就存在一個問題,每個國家所使用的字元編碼表都是不同的。比如我們發送一句“你好,我好喜歡你演的愛情動作電影!”給島國的倉老師,蒼老師電腦上用的是日本的字元編碼表,是以她的電腦無法正确顯示我們發送的内容。這個時候,人們希望有一個世界統一的字元編碼表來存放所有國家所使用的文字和符号,這就是Unicode。Unicode又被稱為 統一碼、萬國碼、單一碼,它是為了解決傳統的字元編碼方案的局限性而産生的,它為每種語言中的每個字元設定了統一并且為之一的二進制編碼。Unicode規定所有的字元和符号最少由2個位元組(16位)來表示,是以Unicode碼可以表示的最少字元個數為2**16=65536。

為什麼已經有了Unicode還要UTF-8呢?這是由于當時儲存設備是非常昂貴的,而Unicode中規定所有字元最少要由2個位元組表示。人們認為像原來ASCII碼中的字元用1個位元組就可以了,是以人們決定建立一個新的字元編碼來節省存儲空間。UTF-8是對Unicode編碼的壓縮和優化,它不在要求最少使用2個位元組,而是将所有字元和符号進行分類:

ascii碼中的内容用1個位元組儲存

歐洲的字元用2個位元組儲存

東亞的字元用3個位元組儲存

...

UTF-8是目前最常用,也是被推薦使用的字元編碼。

我們上面提到過,一般在兩個地方會用到字元編碼:

磁盤寫入或讀取資料時;

程式執行時的輸入和輸出;

磁盤寫入或讀取資料時使用的字元編碼是由編輯器指定的工程或檔案的字元編碼決定的,這與Python解釋器是無關的;但是Python程式執行時,将Python腳本檔案加載到記憶體時所使用的字元編碼是主要問題所在。在Python 2中,Python解釋器預設使用的是ASCII碼,此時如果要運作的程式中如果有中文Python解釋器就會報錯。

這是因為Python解釋器執行該程式時試圖從ASCII編碼表中查找中文字元對應的二進制序列,但是發現找不到。此時要想該程式正常運作,就需要在python腳本檔案的開始位置聲明該檔案的所使用的字元編碼:

需要說明的是: Python 3的解釋器預設使用Unicode編碼,它本身是可以對中文字元進行編碼和解碼的,是以即便不指定字元編碼也能正常運作,但是還是建議保留字元編碼的聲明。

通常python腳本都是跑在Linux上的,為了讓python腳本檔案可以像shell腳本那樣可以直接調用執行,我們通常需要在python檔案最開始的位置指定python解釋器:

不建議寫python解釋器的絕對路徑,如:

因為這樣寫的話,将來要想更換python解釋器是非常麻煩的。

關于注釋,有兩個原則:

不寫沒必要的主要:多餘的注釋隻會讓代碼閱讀者看着更亂,且容易分神

錯誤的注釋不如沒有注釋:更改代碼後,首先要做的就是更改注釋

塊注釋,顧名思義,應該是對一個代碼塊的注釋。顯然,對某個代碼塊的注釋資訊應該寫在這個代碼塊的前面,并且縮進到與該代碼塊相同的級别。塊注釋的每一行都要以#号加上單個空格開始(注釋中的縮進文本除外):

說明: Python中的單行注意與多行注意都是以# 号來辨別的。如果注釋資訊隻有一行,則為單行注釋;如果注釋資訊有多行,則為多行注釋。另外如果多行注釋中有多個段落,則段落之間可以以一個#加單個空格的空注釋行隔開。

如果要注釋的代碼塊隻有一行代碼,且注釋資訊也很短,也可以把直接注釋要寫在代碼的後面,這就是 行内注釋 。行内注釋要求代碼與#号之間至少要有2個空格,同時#号與注釋内容之間至少要有1個空格。

另外,行内注釋并不被推薦使用。

文檔字元串通常用來為某個子產品、函數、類或方法提供比注釋更詳細的使用說明、注意事項、使用用例等幫助資訊。文檔字元串以三個引号(單引号和雙引号都可以,通常都使用雙引号)将字元串包起來。由于文檔字元串表現形式類似于Python的多行字元串,是以很多人把它當做Python中的多行注釋來用。

PEP 276 中對“什麼是好的文檔字元串的書寫格式”進行了一些定義:

應該為公共子產品、函數、類和方法編寫文檔字元串。非公共方法需需要docstring,但是應該有一個描述該方法的注釋,且該注釋資訊應該出現在def行的行末。

子產品的文檔字元串應該寫在“字元編碼的聲明”與“子產品導入”語句之間;函數與方法的文檔字元串應該寫在def語句行與函數體或方法體正式代碼之間;類的文檔字元串應該寫在class語句行與該類的第一個方法定義之間。

如果文檔字元串有多行,那麼結尾的三個引号應該在一個單獨的行。

如果文檔字元串隻有一行,那麼結尾的3個引号應該與開始的3個引号以及文檔字元串在同一行。

來看下Python 3中一些内置函數的文檔字元串執行個體:

當Python内置的核心子產品提供的功能無法滿足我們的需求時就需要導入外部子產品,而導入子產品的功能有兩種方式:

import MODULE :導入整個子產品

from MODULE import XX :導入子產品中的一部分(方法、變量、或常量等)

例如,要想檢視或更改python查找子產品的路徑清單就需要使用sys子產品下的path變量;若需要執行系統指令可以使用os子產品下的system()方法。

Python基礎文法

我們在寫shell腳本時,經常會通過接受執行腳本時傳入的變量來做相應的操作,來保證腳本的靈活性。比如我們要寫一個腳本來調用ping指令對指定的域名進行ping測試,這時候顯然将域名當做參數傳遞給腳本要比把域名寫死在腳本中靈活的多。shell中可以隻用$1,$2這樣的特殊變量來擷取傳入的參數,而python中需要用sys子產品下的argv變量來擷取。

sys.argv是一個清單,與shell相同,其第一個元素是目前腳本的名稱,之後才是傳入的參數。

編寫一個ping.py,内容如下:

執行該腳本,結果如下圖所示:

Python基礎文法

在Java和C語言中用花括号{}包起來的部分就是一個代碼塊,shell腳本中的代碼塊是由專門的開始和結束辨別的,而python中的代碼塊是靠“縮進對齊”來表示的。下面我們分别一個if-else的條件判斷來對這幾個語言的代碼塊表示方式做一個對比:

在之前的文章我們已經解釋過:Python是一個動态的、強類型的、解釋型的程式設計語言。而實際上,解釋型語言與編譯型語言的界限正在變得模糊。包括Python在内的很多進階程式設計語言,會将源代碼先編譯成特定類型的中間代碼,然後再由解釋器去執行,這樣可以提高執行效率。Python的解釋器同時也是生成Python中間代碼的編譯器,.pyc檔案就是存放Python中間代碼的檔案。執行Python代碼時,如果該源碼檔案導入了其他的.py檔案,那麼執行過程中會自動生成一個與導入的.py檔案同名的.pyc檔案。

      本文轉自zsdnr  51CTO部落格,原文連結:http://blog.51cto.com/12942149/1928959,如需轉載請自行聯系原作者