python入門,程式設計基礎概念介紹(變數,條件,函式,迴圈)

diwugebingren發表於2019-04-05

學一門程式語言正在變得越來越容易,只要念過高中(甚至是初中、小學),能熟練聊qq和懂得一點點office軟體的人,入門一門程式語言都不在話下。我們跟別人溝通,靠的是語言,無論是說出來還是寫出來,也不管是普通話還是英語。那麼想要跟計算機溝通,也需要靠語言,世界上現在有很多跟計算機溝通的語言,有c,jave,javascript,php,python……這些都是程式語言,它們跟我們與別人交流的語言有何不同呢?我們與別人交流的語言是自然形成的,而程式語言是由某個人或者某幾個人編寫出來的。自然形成的我們稱為自然語言,程式語言則屬於人工語言。自然語言的語法較為鬆散,自由,既可以用來解決問題,也可以抒發感情、講述故事。而計算機最初被設計的時候是用來解決各種現實生活中的問題的,所以邏輯嚴謹,說一不二,那麼跟計算機溝通的時候也需要邏輯嚴謹,不容含糊,語法嚴格,這大概就是很多人覺得程式設計困難的地方吧。但不要緊,一旦我們習慣了這種嚴謹的語法和思考方式,將會大大提高我們解決問題的效率和正確率。

計算機使用的是二進位制,通過接受到的指令執行任務,最初人們通過組合語言(assembly language,低階語言)來與計算機溝通,告訴cpu執行什麼樣的指令,可是各個不同的計算機系統結構都各自有不同的彙編(assembly),並且用匯編編寫程式效率低下(畢竟彙編更偏向於跟計算機溝通),所以對人類友好的高階程式語言應運而生(比如c語言),人們通過編譯程式(充當了一個翻譯家的角色)把高階程式語言編譯成計算機可以理解的機器程式碼。這時候程式設計已經變得比之前容易了,然而更加高階的現代程式語言不斷產生,使得程式設計的入門門檻進一步降低,python就是其中一門現代程式語言。

python是一種解釋型語言,也就是說用python編寫好的程式不需要提前編譯,而是在執行時由直譯器一行一行地把python原始碼翻譯成cpu可以讀懂的機器程式碼。要執行python程式,需要從python官網下載python軟體,安裝到自己的電腦上。從官網下載下來的python軟體中帶有CPython,這是用c語言寫成的python直譯器,我們在命令列下執行用python編寫的程式時,就是在用CPython這個直譯器來翻譯程式。世界上還有其他各種python直譯器,比如Jython(執行在Java平臺上的Python直譯器,可以直接把Python程式碼編譯成Java位元組碼執行),但CPython的使用是最廣泛的。經過多年發展,python最新版本(截止寫作這篇文章之時)已經是3.7了,現在主要有兩個大的不同版本的python,一個是python2.x.x,另一個是python3.x.x,這兩個版本在實際使用中會有些微的不同,這次我們用python3.x.x來介紹程式設計中的基本概念。

1.準備工作

linux和mac一般都自帶python2。

某些最新版本的linux發行版可能也自帶python3,如果沒有,請參考這裡來安裝使用。

最新版本的mac一般都自帶python3,如果沒有,請參考這裡來安裝使用。

Windows系統可以從www.python.org/downloads/下載python軟體(直譯器),下載最新版python3.x.x。安裝的時候勾選Add Python 3.x to PATH。這樣就自動設定好了python的環境變數(環境變數就是設定python程式的相關路徑,讓Windows可以找到python程式的安裝目錄)。

image

python程式設計有命令列和圖形介面( 比如IDLE )兩種方式,下面使用命令列方式,通過命令列執行python程式,通常還需要一個文字編輯器來編寫python程式檔案(這種程式檔案被稱為原始碼)。文字編輯器在Windows下可以使用notepad++,也可以使用Sublime Text(它是跨平臺的,也可以在Linux和mac下使用),還可以使用Visual Studio Code(它也是跨平臺的),可以在網上搜尋這些編輯器的安裝使用教程。

與python直譯器打交道的方式有兩種: 第一個就是python互動模式。在linux下,終端輸入python預設為python2.x.x,輸入python3則為python3.x.x。我們輸入python3來使用python3.x.x,輸入python3後就進入了python3互動模式:

Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
複製程式碼

在windows系統下,需要在cmd(命令提示符)下輸入python進入,如果不知道cmd(命令提示符)是什麼,可以參考這裡

image

“>>>”是python互動模式的提示符(提示你可以在它後面輸入東西),所以我們在“>>>”後面輸入python語句,輸完後點選回車,則python語句立即執行,並列印出執行結果。如果要退出python互動模式,輸入exit()就可以了。

第二個則是用python執行python原始碼。 開啟你熟悉的文字編輯器,編寫程式,在儲存檔案時將檔名以.py為字尾(副檔名,可以起到指定檔案型別的作用)。然後在該檔案所在目錄開啟命令列,比方說該檔案叫filename.py,則輸入python filename.py,點選回車,執行該檔案中的程式。

image

2.基礎概念

我們編寫程式的時候,要在英文輸入法下輸入各種符號,不然程式會報錯。像下面這樣,我故意在中文輸入法下輸入雙引號,出現了“SyntaxError”錯誤:

>>> “李”
  File "<stdin>", line 1
    “李”
      ^
SyntaxError: invalid character in identifier
>>> 

複製程式碼

我們可以把python互動模式直接看做一個命令列的計算器來使用,比如輸入4+5點選回車,python互動模式下就會顯示計算結果。

>>> 4+5
9
>>> 

複製程式碼

可以嘗試在互動模式下進行不同的計算,“+”表示加法,“-”表示減法,“*”表示乘法,“/”表示除法。

>>> 5*6
30
>>>2/3
0.6666666666666666
>>>

複製程式碼

“%”表示除餘,就是說結果會返回一個數被另一個數整除除不盡時的餘數:

image

>>> 9%2
1
>>> 0%2
0
>>> 1%2
1
>>> 2%2
0
>>> 3%2
1
>>>

複製程式碼

“**”表示冪運算,比如輸入4**2則表示4的二次方:

>>> 4**2
16
>>>

複製程式碼

“//”表示一種特殊除法,結果返回商的整數部分(向下取整),比如9//5,9除以5為1.8,那麼9//5的結果就取了1.8的整數部分:

>>> 9//5
1
>>>
複製程式碼

“+”,“-”,“*”,“/”,“%”,“**”,“//”這些符號表明瞭應該怎麼樣來操作這些符號之前和之後的兩個數字,比如,4+5就說明了需要把4和5加起來,所以這些符號就叫操作符。而像4+5這樣操作某些數的式子,叫做表示式,4+5這個表示式是比較簡單的,(4+5)/2這個表示式就複雜了一些,通常把一個數字本身也叫做表示式。

2.1變數

如果我們想計算一個複雜一點的表示式,比如(5/6)+((4/(4+5))*((3/2)-8)),由於它的計算過程相對複雜,因此很難理解這個式子具體做了什麼樣的操作。這時候我們想要看懂這個表示式所表達的意義,就希望能夠拆分它,通過給計算過程中的某些中間結果一些“名稱”就可以拆分成很多步了。比如(4+5)/2,我們首先給4+5起一個“名稱”,就叫做a吧。現在我們就可以把(4+5)/2拆分成兩步:

a是4+5的“名稱” #第一步
a/2            #第二步
複製程式碼

像上面這樣子寫的東西叫做虛擬碼(Pseudocode),可以通過虛擬碼來大致描述一個程式的計算流程跟步驟,在這個虛擬碼中,第一行程式碼會首先執行,第二行程式碼會在第一行程式碼執行完成後執行,其實在真正的原始碼檔案中,程式碼也是如此執行的,從檔案第一行開始,自上而下,逐行執行,直到最後一行程式碼被執行完。“#”後面跟的文字包括“#”是程式碼中的註釋,編譯器或者直譯器會忽略掉這部分內容,寫註釋是為了增加程式的可讀性,當時寫的程式很可能作者會明白程式表達的東西,但是過一兩個月可能就會連作者自己都不知道,所以為了給作者自己或者別人閱讀原始碼提供便利,要儘量在註釋裡解釋介紹程式的作用或者思路。

在計算機術語中,給某個計算過程的某些中間結果起的“名稱”就是變數(variable)。該用什麼符號來表示變數呢,各種程式語言給我們的自由度非常高,除了避開程式語言中保留的某些關鍵符號(關鍵字)和一些會與其他東西產生混淆的符號,並注意不能把數字放在變數名中的第一個位置(例如“0a”就是一個不合法的變數名),我們可以使用任何字母、標點符號、數字的組合(中文和中文標點除外),為了程式碼的可讀性,儘量使用具有描述性的單詞,比如user,id,phone_numbers……等。我們編寫的程式可能會很長很長(程式很複雜),比如說可能會有1000行,那麼通過各種變數,我們一步步的計錄下程式執行過程中所得出的一些結果,再把這些結果提供給後面的程式,直到得出最終結果。在程式的世界裡,給變數賦值的符號是“=”(不同於數學中這個符號的用法),上面的虛擬碼在python程式中可以實現如下:

a=4+5   #變數a得到4+5的值
a/2     #(4+5)/2的值
複製程式碼

這是兩行python程式碼,你把它複製到python互動模式的提示符中點選回車,得到如下結果:

>>> a=4+5   #變數a得到4+5的值
>>> a/2     #(4+5)/2的值
4.5
>>> 
複製程式碼

但是你將它複製到一個檔案中,並把檔名改為example.py,然後在python命令列模式下輸入python example.py(在linux下,要使用python3就得輸入python3 example.py),點選回車,程式不會顯示任何結果:

image
這就是python兩個模式下的區別,互動模式會自動列印出結果,命令列模式下則不會列印出結果(除非你自己告訴程式列印出哪個結果(變數))。互動模式下寫的python語句能立即執行,但無法儲存,不能重複使用。所以想要寫複雜一點的程式就要寫入python原始碼檔案中。

我們已經知道了什麼是變數,並知道如何給變數賦值。一個變數呢,就像一個空盒子,賦值就是給盒子裡塞東西。塞進去的是4那該變數就表示4,塞進去的是4+5那該變數就表示4+5的值。所以,給變數進行多次賦值是允許的,只不過在變數再次被賦值時,上次賦的值就被抹去了。我們要用到一個變數的時候,必須先宣告這個變數。第一次給剛宣告的變數賦值叫做初始化一個變數。在python中,宣告變數跟初始化變數是一步完成的,就是給出變數名並賦一個值給它:

#該變數名第一次出現,所以下面的語句
#是宣告和初始化了該變數
a=7

複製程式碼

現在我們需要擴充套件下我們的認知,計算機程式中的變數不光可以表示數字表示式(例如4+5)的值,還可以記錄、儲存一些文字內容,比如這句英文:life is but a dream.這種文字性的內容我們可以看做是一串字元的序列(有順序的一串符號,想象用一條線串起不同的符號,符號的位置是固定的),這種序列稱為字串。在python中,用雙引號""或者單引號''來圈住字串,也可以說是用""或者''來表示引號中間的內容就是字串。下面舉幾個例子:

#給變數str1賦值,值的內容是字串"life is but a dream"
str1="life is but a dream" 
#給變數str1繼續賦值,任何符號都可以成為字串,包括數字以及空格
str1='12' 
str1=' '
#字串可以用“+”串聯起來
str1="life is but a dream"+"12"
str2="hello"+str1
str3=str1+str2
#給變數number1賦值,值的內容是數字12,給某個變數賦予數值直接寫上數值
number1=12
#給變數number1再次賦值
number1=37

複製程式碼

在python中,變數可以表示任何東西,一個變數可以多次賦予不同型別的值:

a=5
a="5"
a='string'

複製程式碼

一個程式語言有了這種特性,我們就可以說這個程式語言是動態型別語言(動態語言),很顯然,python是動態型別語言(動態語言)。

在一些更為傳統的程式語言裡,儲存數字的變數跟儲存字串的變數是有區別的,儲存數字的變數不能把字串賦值給它,儲存字串的不能把數字賦值給它,需要變數的時候首先要通過程式語言裡的識別符號(程式語言裡保留的一些表明變數的值的型別的字元)來表明這個變數是要儲存什麼的,然後隔個空格跟上變數名稱,這叫做宣告一個變數,例如在c語言中,宣告一個整數型別的變數可以這樣做:

int a;  //宣告一個int變數
a=3;   //初始化變數,a是int變數,所以賦值的時候只能是整數
a="3"  //這在c語言中是不允許的

複製程式碼

像這種宣告變數時需要指定型別(並且一旦指定型別,賦值的時候只能賦予與變數型別符合的值)的程式語言被稱為靜態型別語言(靜態語言)。一般的,變數裡儲存數字時可以分為整數(int),浮點數(float),整數(int)的概念我們在數學裡學過,那麼浮點數(float)到底是什麼呢,其實我們在數學裡也是學過的,那就是小數(有小數點的數)。在計算機裡,浮點數跟整數的儲存方式不同,所以有必要分清兩者的概念。

#把一個整數賦值給變數
number1=123
#把一個浮點數二次賦值給同一個變數
number1=12.44

複製程式碼

2.2條件

前面我們已經說到程式自上而下一行行執行,那如果我們想要程式不再這麼無聊的執行下去,而是有選擇的執行某一段程式碼,該怎麼辦呢?那就要通過設定判斷條件來把程式分隔成一塊一塊兒,程式在執行時根據當時的情況來判斷符合哪個條件從而執行那個條件下的一塊程式碼。比如我們想要實現一個“飲料選擇器”,當溫度低於10攝氏度時,我們就喝熱飲,當溫度等於或者大於10攝氏度時,我們就喝冷飲。用虛擬碼可以表示:

if temp<10:
    #下面是一段程式碼塊
    喝熱飲
    ……
    ……
    #上面是一段程式碼塊
else if temp>=10:
    #下面是一段程式碼塊
    喝冷飲
    ……
    ……
    #上面是一段程式碼塊

複製程式碼

上面的虛擬碼中,if,else if表示了它們在英文裡相同的意思(if表示如果,else if表示否則如果),在一般的程式語言裡,if,else if 是關鍵字,它們同其他一些關鍵字被程式語言保留,你想要起變數的名字(後面我們還會給函式起名字)都不能使用這些被保留的關鍵字,因為關鍵字在程式中表示了特殊的意思,比如在這兒if,else if 後面跟上表示式就是一個條件語句。而條件語句後面就可以跟一段程式碼塊,跟其他地方的程式碼區分開來,上面虛擬碼中可以把註釋中間的東西想象成很長的一段程式碼塊。

上面虛擬碼中的“temp<10”是一個表示式,“temp”看做儲存溫度的變數,“<”這個符號跟數學裡的意義一樣表示“小於”,那麼“temp<10”這個表示式的值就有兩種可能,一種就是“temp”變數的值大於10,另一種就是“temp”變數的值小於10。在第一種情況下,“temp<10”這個表示式顯然不符合事實,所以“if temp<10:”下面的程式碼塊不會執行,與之相對應的,“else if temp>=10:”下面的程式碼塊就會執行。在第二種情況下,“temp<10”這個表示式顯然符合事實,所以“if temp<10:”下面的程式碼塊會立即執行,與之相對應的,“else if temp>=10:”下面的程式碼塊則不會執行。這樣就達到了有選擇的執行某一段程式碼的目的。

像“temp<10”或者“temp>=10”這樣的表示式可以稱為比較表示式,像“<”或者“>=”這樣的操作符可以稱為比較操作符。常見的比較操作符如下:

操作符 解釋
< 小於
<= 小於等於
> 大於
>= 大於等於
== 等於
!= 不等於

比較表示式的值如何表示呢,這裡我們需要再次擴充套件我們的變數所能表達的型別,變數除了表示數字、文字內容,還能表示比較表示式(比如“temp>=10”)的值,從前面的解釋中我們知道比較表示式的值就兩種可能,一種符合事實,這時候我們就規定比較表示式的值為True(也可以用數字“1”表示),另一種不符合事實,這時候我們就規定比較表示式的值為False(也可以用數字“0”表示)。這種只有兩個值(True和False)的變數型別稱為布林(boolean)型別。

一般來說,if,else if這兩個關鍵字後面跟的比較表示式的值是相反的,所以就只會執行比較表示式的值為True的那個條件語句下的程式碼塊。另外還有包含else關鍵字的條件語句,else後面會省略比較表示式,當if或者else if條件語句中比較表示式的值都為Flase的時候就會執行else條件語句下的程式碼塊。假如temp變數的值為11,可以想想下面的虛擬碼中到底會執行哪一個程式碼塊:

if temp<=10:
    喝熱奶茶
    ……
    ……
else if temp>=15:
    吃冰激凌
    ……
    ……
else:
    喝涼開水
    ……
    ……

複製程式碼

比較表示式也可以串聯在一起使用,比如你想表達溫度大於10並且小於15時,就要用and這個操作符把temp>10temp<15給串起來,則表示式就變成了temp>10 and temp <15;當你想要表達溫度大於10或者小於15時,就要用or這個操作符把temp>10temp<15給串起來,則表示式就變成了temp>10 or temp <15;當你想表達溫度大於10這個事實不成立時,就要給temp>10之前加上not操作符,表示式變成了not temp>10

andornot被稱為布林操作符(在python語言中),因為這些操作符的作用就是串聯起別的比較表示式來改變整個表示式的布林值。當然在別的程式語言中,這些操作符會有所不同,這是無關緊要的,重要的是操作符所起到的功能。

表示式 功能
a and b a與b的布林值都為True則a and b為True,否則為False
a or b a與b的布林值有一個為True則a or b為True,否則為False
not a a的布林值為True則not a為False,a的布林值為False則not a為True

假如temp變數的值為9,可以想想下面的虛擬碼中到底會執行哪一個程式碼塊:

if temp<=10 or temp>=15:
    什麼都不喝
    ……
    ……
else:
    喝涼開水
    ……
    ……

複製程式碼

細心的你可能已經發現了,在“if temp<10:”或者“else if temp>=10:”這兩個條件語句中,末尾都有一個“:”,事實上上面的虛擬碼是基本符合python語法的,在python中我們通過關鍵字後面隔個空格,再寫上比較表示式,末尾再加上“:”的方式來表明一個條件語句,再更加細緻一點,你會發現條件語句之下有一段程式碼全是相對於條件語句來說向右縮排的,一般是打四個空格來實現這樣的縮排,通過這樣的縮排來表明自身是受條件語句約束的程式碼塊。在python裡,通過“:”和縮排來實現程式碼塊,下文要講到的迴圈、函式、物件等也能通過這樣的方式實現受其約束的程式碼塊。在其他程式語言裡,一種實現程式碼塊的方式是通過“{”和“}”把程式碼包裹起來實現的,該小節開頭的虛擬碼可以寫成這樣:

if (temp<10) {
   喝熱飲
    ……
    ……
 }
else if (temp>=10){
    喝冷飲
    ……
    ……
}
複製程式碼

一般來說呢,程式語言裡會有if條件語句,else if條件語句,else條件語句,switch條件語句。在python的語法裡,else if變成了elif,更加簡潔了,並且沒有switch語句。該小節開頭的虛擬碼我們可以寫成python原始碼:

temp=10
drink="喝什麼"

if temp<10:
    drink="喝熱飲"
elif temp>=10:
    drink="喝冷飲"

複製程式碼

再多寫個例子:

temp=16
drink="喝什麼"

if temp<10:
    drink="喝熱飲"
elif temp>=10 and temp<=15:
    drink="喝涼開水"
else:
    drink="吃冰激凌"
#想想,最後drink的值是什麼?

複製程式碼

2.3函式

如果我們想要在程式執行的過程中與人互動(與別的程式或者程式片段互動),那麼我們就需要引入未知數。這個未知數會在程式執行過程中實時地得到某人(其他程式)的輸入(input),從而程式根據輸入(input)的資料計算下去。

比如我們想計算小萌某一天走過的路程有多遠,已知小萌的行進速度是5公里每小時,那麼我們不知道的就是小萌在某一天到底走了多長時間,這個未知數我們可以暫時先用t來表示,這樣我們就能夠用t*5來表示小萌某天走過的路程。

我們現在想要計算小萌今天的路程,則只需要問問小萌今天走了多長時間的路,小萌說走了2.5小時,我們把t*5中的t換成2.5,再計算下就知道小萌走了12.5公里。

像這個例子中的t*5(t是未知數,未來會得到一個具體輸入(input))這樣,包含了未知數的這種構造就是函式(function)。該小節開頭所說的讓程式在執行過程中得到一個具體輸入(input)就需要函式這樣的構造。函式中的未知數被稱為該函式的引數。

該小節第二段的例子展示了定義一個函式的過程,用t*5計算出來的路程就是函式的輸出(output),也可以說是函式的結果。那麼t*5其實可以看作函式本身。t是函式的引數,我們也可以用a來表示則函式本身成為了a*5,a*5t*5是等價的,函式的引數名稱與函式的執行結果無關。既然函式的引數可以用任意名稱來表示,那麼函式本身呢?函式本身也能用任意名稱來表示,比如這裡我們可以用mile來表示t*5,以後我們就可以把t*5直接叫mile函式。在python中,定義這個函式需要這樣做:

"""
如你所見
這是一個多行註釋
首行和末尾行用要用三個雙引號包裹起來哦
"""
"""
def是定義函式的關鍵字,mile是函式的名稱(名稱可以自由的發揮想象力),
圓括號裡的是函式的引數(引數名稱可以自由的發揮想象力),return是函式返回某個值的關鍵字。
"""
def mile(t):
    m=t*5   
    return m #返回變數m的值

複製程式碼

該小節的第三段展示了我們人類使用一個函式的過程,而在程式裡,不需要我們人類操心,我們只需要把引數丟進函式,函式就會計算出結果來。我們可以把函式看作黑盒子,不需要知道函式的具體實現過程。我們可以使用別人定義好的函式,只需要知道函式的引數和函式的返回值(或者函式的作用),以及函式的名稱。這樣我們就不用什麼都靠自己編寫實現,而可以站在巨人的肩膀上專心編寫自己的程式邏輯。假如一段很長的程式碼都是為了得到某個結果,而在程式裡你需要多次計算在不同引數輸入下的這個結果,把這段程式碼用定義函式的方式包裹起來,可以達到重複使用這段程式碼的效果。函式的使用在程式裡我們稱為函式的呼叫,在python中,呼叫上面剛剛定義的mile函式需要這樣做:

#給mile函式填入引數2,然後將mile函式返回的計算結果賦值給變數n
n=mile(2)

#引數也可以使用之前初始化好的變數,看下面的例子
a=3
b=mile(a)

複製程式碼

函式的引數跟變數一樣,也是有各種型別的,有數字、字串、布林值……在定義函式的時候要想清楚輸入的引數是什麼型別,比如我們之前定義的mile函式,它的引數就應該是數字,當你輸入不是數字的引數時,就會得到奇怪的結果:

image

函式的引數可以是任意多個,引數之間用逗號隔開:

def addTwo(a,b):
    return a+b

複製程式碼

函式的引數可以沒有,也可以不返回任何值:

def foo():
    """
    pass語句表示什麼也不做,當你沒有想好函式的具體實現時
    可以用pass語句先代替
    """
    pass
    
複製程式碼

python直譯器內建了一些函式,我們可以直接拿來用,最常用的就是print函式。這個函式的作用就是在命令列下列印出函式引數中輸入的字串,你可以在互動模式下試試:

print("hello,world!")

複製程式碼

另一個常用的函式就是input函式。這個函式的作用就是在命令列下接受使用者的輸入,你可以在互動模式下試試:

input("請輸入一句話: ")

複製程式碼

現在我們用2.2小節關於溫度的例子寫一個示例程式,把我們目前學習到的概念都運用一下:

"""
首先我們定義個函式,把2.2小節例子中的條件語句用函式包裹起來,
以便複用這段程式碼
"""
def drink_selector(temp):
    
    t=int(temp) #int函式內建函式,可以把字串轉換為整數

    if t<10:
        print("喝熱飲")
    elif t>=10 and t<=15:
        print("喝涼開水")
    else:
        print("吃冰激凌")

"""
我們從使用者輸入中得到temperature變數的值
input函式得到的使用者輸入是字串
"""
temperature=input("請輸入當前溫度: ")

#呼叫我們之前定義好的函式,讓函式告訴我們該喝什麼飲料
drink_selector(temperature)

複製程式碼

程式執行如圖所示:

image

前面說到函式是個黑盒子,意思就是:如果把整個程式看做一整個解決某個大問題的流程(步驟)的話,定義一個函式,就好比預先定義了一個解決這個大問題裡的某一特定小問題的流程(步驟)的模板,一旦呼叫該函式,則解決該大問題的流程就變成了解決該大問題裡這個特定的小問題的流程(步驟)了。當函式返回結果或者函式內部流程結束,對該函式的呼叫結束,解決該大問題的流程繼續。因此,函式內部的運作可以說是在不同的流程裡,在函式之外是不可見的,但是因為它的流程是在整個程式的流程裡,所以它可以使用、修改函式之外的變數。函式內部定義的變數從該函式外部是無法訪問到的,這樣的變數被稱為區域性變數,而在整個程式的所有地方都能訪問到的變數被稱為全域性變數

x=0 #全域性變數

def blackbox():
    y=3 #區域性變數

blackbox()
#str函式是內建函式,將數字轉換為字串
print(str(y))

複製程式碼

上面的這段程式碼因為從函式外部無法訪問到函式內部定義的變數y,所以程式執行中會出現NameError: name 'y' is not defined:

image
像上面這樣在程式執行過程中出現錯誤的程式碼,我們就說程式碼裡有bug(故障,缺陷)。還有一種bug,就是在程式執行過程中會出現奇怪的行為,或者得出的結果與我們希望得到的有出入。

x=0 #全域性變數

def blackbox():
    x=3 #是改變全域性變數的值,還是重新定義了一個區域性變數?
    print(str(x))

blackbox()
print(str(x)) 

複製程式碼

上面這段程式執行結果為下圖:

image

上段程式碼中由於初始化變數與變數的賦值語句的語法相同,導致直譯器無法分清我們在函式內部寫的x=3的意圖何在?是重新定義一個區域性變數還是改變全域性變數x的值?從程式執行結果來看,python在這種情況下選擇了定義區域性變數,而函式外部由於無法訪問函式裡的區域性變數,則會使用外部定義的全域性變數。讓區域性變數跟全域性變數同名是種很迷惑人的做法,所以在定義一個變數的時候應該盡最大可能讓變數名具有唯一性。如果要在函式內部修改全域性變數的值,則可以這樣做:

x=0 #全域性變數

def blackbox():
    """
    下面程式碼先使用global關鍵字後面跟全域性變數x的方式來
    說明此處的x是前面定義的全域性變數x
    """
    global x
    x=3 

blackbox()
print(str(x))

複製程式碼

上段程式碼執行如下:

image

2.4迴圈

任何程式都是自上而下一行行執行,假如我們想要某個函式(某段程式)執行很多次,我們該怎麼辦呢,一種自然的想法就是把這個函式(這段程式)多寫幾遍,想要執行幾遍就寫幾遍,這當然是允許的,比如說,我們想要在終端一行一行的列印出“hello,world!”這句英文的每個字母跟標點,則我們可以這樣做:

print("h")
print("e")
print("l")
print("l")
print("o")
print(",")
print("w")
print("o")
print("r")
print("l")
print("d")
print("!")


複製程式碼

但是當我們想要執行幾百上千遍這個函式(這段程式)時,我們人類是特別不擅長做這種複製貼上的重複工作的,尤其是當這種重複動作達到幾百上千次時,複製過程中甚至會出現難以察覺的錯誤,導致程式執行結果出現偏差。所以這不是好的方法,在各種程式語言裡,可以通過迴圈語句來實現多次執行同一函式(同一段程式),並且能夠在重複執行某個函式(某段程式)的時候每次給予這個函式(這段程式)的引數(變數)都不同。下面的python程式碼跟本小節第一段python程式碼有相同的執行結果,但因為運用了迴圈語句(loop statement)而更加簡潔:

#for迴圈(for loop)
for letter in "hello,world!":
    print(letter)

複製程式碼

這段程式碼裡“for”和“in”是組成迴圈語句的關鍵字,再一次的,python語法裡用“:”作為迴圈語句的結尾,並且該語句下的程式碼是相對於該迴圈語句向右縮排,來表明這是受該迴圈語句約束的程式碼塊。這段程式碼如何迴圈呢?它首先會把“hello,world!”字串中有12個字母數出來,然後根據有12個字母就迴圈12次,也就是讓受該迴圈語句約束的程式碼塊print(letter)執行12次。第一次迴圈則取出第一個字母“h”賦值給引數letter,然後print函式會根據引數letter列印出字母“h”,第二次迴圈則會取出第二個字母“e”……直到第十二次迴圈把“!”取出來列印出來,迴圈結束。看下面一段程式碼:

#另一種for迴圈(for loop)
for index in range(0,12):
    print("hello,world!"[index])

複製程式碼

這段程式碼跟上一段程式碼的作用一樣,都是分行列印出“hello,world!”的每個字元,但用到了另一種形式的迴圈,這種迴圈更為傳統,就是通過數字索引的方式達到迴圈的目的。range函式是個python內建函式,根據提供的引數012會給迴圈提供一串從011的索引數字,索引數字的取值範圍包括左邊的0但不包括右邊的12。第一次迴圈的時候索引index的值為0,第二次迴圈的時候索引index的值為1……直到第十二次迴圈索引index的值為11,這時候索引數字完了,迴圈就結束了。值得特別注意的是,計算機世界裡,計數是從0開始的。所以通過range函式給定了12個索引數字之後,最後一次迴圈給出的索引數字index是11,而不是12。''hello,world!''[index],這是個新的寫法,字串後面用方括號把索引數字包裹起來,則表示從字串中取出對應位置上的單個的字元。在這段程式碼裡,第一次迴圈的時候,index為0,則''hello,world!''[0]就是“h”,第二次迴圈的時候,index為1,則''hello,world!''[1]就是“e”……第十二次迴圈的時候,index為11,這時候從0開始計數已經是第十二次了,所以''hello,world!''[11]就是“!”。再看下面一段程式碼:

string="hello,world!"
count = 0
#len函式是內建函式,返回字串的長度
while count <len(string):
    print(string[count])
    #下面的程式碼表示增量,每一次迴圈count的值加1
    count=count+1

複製程式碼

這段程式碼跟上一段程式碼作用相同。這段程式碼用到了while這個關鍵字,這是又一種迴圈方式,叫while迴圈(while loop),當count變數的值小於"hello,world!"的總長度時,就繼續迴圈下去:

  • 第一次迴圈,count變數的值為0,count <len(string)的值為True,所以受該迴圈語句約束的程式碼塊執行一次,當count=conut+1執行之後,count的值變為1;
  • 第二次迴圈,count變數的值為1,count <len(string)的值為True,所以受該迴圈語句約束的程式碼塊執行一次,當count=conut+1執行之後,count的值變為2;
  • ……
  • ……
  • 第十一次迴圈,count變數的值為10,count <len(string)的值為True,所以受該迴圈語句約束的程式碼塊執行一次,當count=conut+1執行之後,count的值變為11;
  • 第十二次迴圈,count變數的值為11,count <len(string)的值為True,所以受該迴圈語句約束的程式碼塊執行一次,當count=conut+1執行之後,count的值變為12;
  • 現在count變數的值都為12,count <len(string)的值為False,退出迴圈。

這種迴圈可以實現無限迴圈:

number=1
#這兒number==1這個比較表示式的布林值永遠為True,所以迴圈永遠繼續
while number==1: 
    print("這個迴圈不會結束")

複製程式碼
while True: #布林值永遠為True,所以迴圈永遠繼續
    print("這個迴圈也不會結束")

複製程式碼

上面的兩種無限迴圈可以使用CTRL+C 來中斷迴圈。但是任何迴圈都是可以在內部中斷的,通過在該迴圈中使用break語句,就可以中斷該迴圈,下面的程式碼就演示瞭如何使用break語句:

number=1
count=0
while number==1: 
    print("這個迴圈不會結束")
    count=count+1;
    if count>18:
        """
        設定break語句,在變數count大於18時,該迴圈中斷
        想想,這個迴圈一共迴圈幾次?
        """
        break

複製程式碼

在python中用在迴圈中的另一個可以改變迴圈行為的語句是continue語句。當出現continue語句時,該迴圈的該次迴圈中,出現在continue語句之後的語句被忽略,不再執行:

#該程式顯示小於12的奇數
for index in range(0,12):
    """
    假如index能被2整除,則為偶數,反之為奇數
    當index是偶數的時候,運用continue語句忽略後面的print語句
    """
    if index%2==0: 
        continue
    print("奇數:"+str(index))

複製程式碼

歡迎瀏覽我的個人部落格,https://diwugebingren.github.io

歡迎關注我的公眾號

相關文章