[Toc]
# 第2章 Python基礎
在今天的學習中,小墨學習了輸入輸出及字符串的內容,還給墨妹妹做了個小游戲。墨妹妹剛開始學習打字,小墨給她做了個什么樣的游戲呢?另外,做游戲時,小墨還遇到了自己的第一個bug,他又是如何來“殺蟲”的呢?一起來看看吧。
時間:早上9:00
地點:墨馨書屋
墨博士:早上好小墨。你現在能熟練使用IDLE了嗎?
小墨:早上好博士。嗯……應該……沒問題吧。
墨博士:回答的不干脆呀。這樣吧,今天呢,我們來學習Python的基礎知識,包括輸入輸出、變量和數據類型等,學習的時候我也再提一下IDLE的使用,你也來看看自己的掌握情況。
小墨:太好了!
# [插圖:墨馨書屋內景]
## 2.1 輸出
墨博士:在第1章中,我們編寫了如下的程序:
```
print('Hello World !')
print('Hello Python !')
```
運行,可以在IDLE窗口中看到結果為:
```
Hello World !
Hello Python !
```
也即打印了print后面的括號里單引號引起來的內容。
我們可能不明白為什么會這樣,但是可能會猜出這樣的結論:
1. print用于向控制臺打印內容
2. print后面括號中的單引號中的內容是什么,就打印什么
到底是不是呢?編寫這段代碼,運行看看結果:
```
print('我開始學Python了')
print('非常的開心')
print('并不像想象的那么難')
```
寫好后按F5運行,結果為:
```
我開始學Python了
非常的開心
并不像想象的那么難
```
三個print,就打印了三次,內容也是單引號中的內容,這樣就驗證了我們的猜測。
在Python中,print的作用就是將括號內的單引號中的內容打印到屏幕上,這個過程,稱為**輸出**
>動動手:自我介紹:使用print()編寫程序,輸出自己的姓名和愛好。
## 2.2 輸入
小墨:博士,自我介紹我已經寫好了,但是寫一些東西然后讓它輸出實在是太無聊了!能不能寫一個程序,可以給其他人用,讓他們輸入自己的姓名、愛好,然后程序自動組裝成類似“我叫xx,我喜歡xx”的語句輸出呢?我覺得墨妹妹會喜歡這樣的小游戲的,她正在學習打字。
墨博士:分析一下,要想完成你說的效果,我們需要知道“用戶輸入”和“組裝”怎么做。
先說用戶輸入,在Python中,想要輸出使用print,對應的,想要輸入就使用input。
現在在IDLE中按Ctrl + N,新建一個窗口,錄入如下內容:
```
input()
```
按下鍵盤上的Ctrl + S,選擇保存的路徑,然后給要保存的文件起個名字,比如叫my_name,然后點擊保存。如圖2.1所示。

圖2.1 保存后的my_name.py文件
然后按下F5,運行該程序。發現什么了嗎?
小墨:在前面學習print時候,每次運行,IDLE窗口中都會先輸出一行類似“======================= RESTART: D:/my_python/hello.py =======================”的內容,然后輸出程序運行的結果,輸出完畢之后又會出現“>>>”。
但是這次運行之后,并沒有以“>>>”結尾。如圖2.2所示。

圖2.2 my_name.py的運行結果
墨博士:這是因為input()用于接收用戶的輸入,如果你不輸入,它就一直在那等著。也就是說程序一直在運行著沒有結束。
小墨:哦原來是這樣。那輸入后是不是就結束了?
墨博士:現在我們隨便輸入點什么,然后按回車鍵,就可以看到程序結束了。如圖2.3所示。

圖2.3 my_name.py的運行結束
這就是輸入的功能了。
小墨:這個輸入有點不友好,運行之后墨妹妹肯定不知道該怎么用,我來修改修改:
```
print('請輸入你的名字:')
input()
```
這樣運行之后,會現有一句提示,就好多了。
墨博士:嗯加上友好提示,程序就更棒了。這個功能還可以通過在input后面的括號中加入單引號引起來的一句話來實現。將my_name.py中的內容修改如下:
```
input('請輸入你的姓名:')
```
你看,修改之后可以發現窗口名稱的兩邊又出現了星號,還記得這是什么意思嗎?
小墨:出現星號說明文件做了修改沒有保存。
墨博士:沒錯,不光是新建文件需要保存,修改之后的文件我們也需要保存。此時按下Ctrl+S,就可以看到星號消失了。
再次運行、就可以看到友好的輸入提示了。輸入內容后回車結束程序,效果如圖2.4所示。

圖2.4 my_name.py的運行結果
>動動手:編寫程序,使用input分別讓用戶輸入姓名和愛好。
## 2.3 變量
墨博士:用戶輸入說完了。接下來我們把用戶輸入的內容組裝為“我叫xx,我喜歡xx”的格式并輸出。
拼接之前,你需要先了解**變量**的概念。
小墨,你知道一個圓的面積如何計算嗎?
小墨:這個我小學就學過了,圓的面積等于π乘以半徑的平方。π是圓周率,是個無盡的小數,我會背小數點后面的100位,3.141592653589793……
# [插圖:π]

墨博士:停~停~停~,現在呢,我們用Python代碼來計算下半徑為1、2、5的三個圓的面積并輸出,π不需要取那么多位,就取到3.1415926吧。程序可以這樣:
```
print(3.1415926*1*1)
print(3.1415926*2*2)
print(3.1415926*5*5)
```
小墨:這個星號是什么呀?
墨博士:在Python中*號就表示數學上的乘積關系,程序運行,你看,這樣就計算好了:
```
3.1415926
12.5663704
78.539815
```
在這個程序中,我們發現這個π的值被重復寫了三次,麻煩不說,還容易寫錯。那么我們能不能定義一個符號,比如說a,就表示π的值,然后讓a去代替這個π的值去計算呢?大概思路是這樣的:
先讓a 表示3.1415926,那么程序就變為:
```
print(a * 1 * 1)
print(a * 2 * 2)
print(a * 5 * 5)
```
>墨博士提醒:按照Python的編碼規范,運算符的兩邊要留一個空格,比如寫“a * 2”,而不是“a*2”,雖然計算結果上沒有區別,但是前者更規范,風格更好,程序可讀性更好。
這里的a就是變量,簡單的說,就是用一個符號去表示一個數或計算結果,這個符號就稱為變量,比如這里的a。
那么如何讓 a 表示3.1415926呢,很簡單:
```
a = 3.1415926
```
這樣就可以了。注意這里的“=”不是數學中的等于,而是編程語言中的“賦值運算符”,它的運算順序是從后往前的,作用是將后面的內容“賦”給前面的變量。這樣把3.1415926賦值給a之后,a就可以表示3.1415926了。
小墨:我明白了,這個a就像一個代詞,現在代指3.1415926這個數。
墨博士:是的,另外變量的**變**體現在哪兒呢?其實是這樣的:
新建一個文件,輸入這段代碼:
```
a = 3.1415926
print(a)
a = 2
print(a)
```
并保存運行,可以看到先輸出了3.1415926(第2行),接著又輸出了2(第4行),也就是說a所表示的值是可以變化的,它可以一會表示這個,一會表示那個,給它賦了新值,它就表示新的內容了,這就是所謂的變。
回到我們的程序,由于我們不知道用我們程序的人會輸入什么名字或愛好,就可以拿一個變量接收用戶輸入:
```
name = input('請輸入您的姓名:')
```
這樣當我們輸入內容之后,輸入的內容就賦給了name這個變量,此時name就可以表示輸入的內容了,name是我們自己起的名字,和上面的a一個道理。
> 墨博士提醒:IDLE中存儲文件時的文件名,以及這里的變量名,起名規則如下:一般全小寫,如果由多個單詞組成則不同單詞之間用下劃線_分割,如first_name。另外要注意,為了程序的可讀性,一般名字起的要見名知意,盡量不要用a123,sdf等無意義的名字。
接下來我們就將輸入的內容輸出,修改程序如下:
```
name = input('請輸入您的姓名:')
print(name)
```
**注意**:和上面輸出a一樣,第二句print后面括號中的name兩邊不要加單引號,表示輸出該變量所表示的值,而加上這個單引號表示輸出name這個單詞本身。
運行結果如圖2.5所示:

圖2.5 my_name.py的運行結果
> 動動手:編寫程序,請分別讓用戶輸入姓名和愛好并分別輸出
## 2.4 字符串
接下來我們把用戶輸入的內容拼接為“我叫xx,我喜歡xx”格式并輸出。
還得先來了解一個新的內容:**字符**和**字符串**
字符是指計算機中使用的文字和符號,比如漢字“我”,數字“1”,英文符號“a”,數學符號“π”等都是字符。
字符串,就是一串字符。字符和字符串的關系如圖2.6所示。
# [插圖:山楂和冰糖葫蘆,類似于下面的關系]

圖2.6 字符和字符串的關系
小墨:原來字符和字符串的關系就是山楂和冰糖葫蘆的關系呀。
墨博士:哈哈是的。在python中,使用單引號或雙引號引起來的內容,我們稱之為字符串。
> 墨博士提醒:字符串用成對單引號''或成對雙引號""表示,一般情況下兩者沒有區別。
下面來說說拼接的事兒。在使用print輸出字符串時,有三種拼接方式。
在IDLE中新建文件并錄入以下代碼:
```
name = input('請輸入你的姓名:')
hobby = input('請輸入你的愛好:')
print('我叫' + name + ',我喜歡' + hobby)
print('我叫', name, ',我喜歡', hobby)
print('我叫%s,我喜歡%s' % (name, hobby))
```
保存后運行,結果為:
```
請輸入你的姓名:小墨
請輸入你的愛好:編程
我叫小墨,我喜歡編程
我叫 小墨 ,我喜歡 編程
我叫小墨,我喜歡編程
```
第1、2行代碼接收輸入并用兩個變量name和hobby表示輸入的姓名和愛好。第3行代碼中有個+號,在Python中加號不僅能用來做數學中的相加計算,還能把一些東西拼接起來,比如這里的+號將“我叫”、“,我喜歡”以及name和hobby兩個變量一起拼接了起來,輸出了完整的一句。第4行代碼通過逗號拼接,從輸出的結果可以看到,這種方式中的逗號轉成了空格。第5行代碼的%s是一個占位符,表示占著這個位置,然后后面跟一個百分號,再跟一對小括號,小括號中放入我們的兩個變量,此時就是把小括號中的name變量的值賦給第一個%s,hobby變量的值賦給第二個%s,也即前面有多少%s,后面就放幾個變量,并且%s的順序和變量的順序一致,如果前面只有一個%s,則后面的小括號省略不寫。比如:
```
print('我叫%s' % name)
```
這種用法最多,寫起來也最方便,后面我們會經常和它打交道。多寫幾遍,嘗試下不同的情況,你就能熟練掌握這三種方式了。
小墨:好的,這樣就完成輸入名字再輸出的功能了,我今天回去就可以讓墨妹妹用用我編寫的程序了。
墨博士:需要注意的是:第2、3種拼接方式,只用于print輸出語句,而第一種加號的方式,可以用于任何需要字符串拼接的地方,比如:
```{}
s1 = 'hello '
s2 = 'world'
s3 = s1 + s2
s4 = 'hello ' + 'world'
print(s3)
print(s4)
```
輸出結果為:
```
hello world
hello world
```
代碼的第1、2行是將兩個字符串Hello和World賦值給s1和s2,也即用變量表示。代碼的第3行s1和s2這兩個字符串使用+號拼接,拼接的結果賦值給s3。
第4行是直接將兩個字符串用+號拼接然后賦值給了變量s4。
> 動動手:請輸入您的python考試成績,最終輸出為:您的python成績是89分
## 2.5 數據類型
墨博士:小墨,來看這段代碼:
```
a = 2
b = 3
print('a + b = ' + (a + b))
```
你覺得運行會輸出什么?
小墨:您剛才有提到這個+號可以用作數學上的相加計算,所以這里應該會輸出a + b = 5吧?
墨博士:Python中的+確實既可以用來做數學相加計算,也可以用來拼接一些內容。但是這個程序的運行結果可能和你想的不太一樣,如圖2.7所示:

圖2.7 運行報錯
運行出bug了!小墨,你聽說過bug嗎?
> bug詞語由來:Bug一詞的原意是“臭蟲”或“蟲子”;而在電腦系統或程序中隱藏著的一些未被發現的缺陷或問題,人們也叫它“bug”。
“Bug”的創始人格蕾絲·赫柏(Grace Murray Hopper),是一位為美國海軍工作的電腦專家,也是最早將人類語言融入到電腦程序的人之一。而代表電腦程序出錯的“bug” 這名字,正是由赫柏所取的。1947年9月9日,赫柏對Harvard Mark II設置好17000個繼電器進行編程后,技術人員正在進行整機運行時,它突然停止了工作。于是他們爬上去找原因,發現這臺巨大的計算機內部一組繼電器的觸點之間有一只飛蛾,這顯然是由于飛蛾受光和熱的吸引,飛到了觸點上,然后被高電壓擊死。所以在報告中,赫柏用膠條貼上飛蛾,并把“bug”來表示“一個在電腦程序里的錯誤”,“Bug”這個說法一直沿用到今天。
與Bug相對應,人們將發現Bug并加以糾正的過程叫做“Debug”(中文稱作“調試”),意即“捉蟲子”或“殺蟲子”。
# [插畫:bug,類似下圖]

小墨:這個我曾經聽墨哥哥提起過,他說公司給配了最新的電腦,這樣他的編程效率提升了,就能寫出更多的bug來了。
墨博士:……,墨哥哥那是開玩笑的。有bug了要趕緊debug才對,不過也不用太緊張,IDLE給了我們足夠的出錯提示信息幫助我們修復bug,如圖2.7所示。
這里的報錯信息告訴我們,程序data_type.py的第三行出了問題,也即`print('a + b = ' + (a + b))`出了問題,所以你看,IDLE已經很明確的指出了程序出錯的原因,接下來根據它的提示去解決問題就好了。
這里我們程序運行出問題的原因,是“TypeError: must be str, not int”,叫“類型錯誤,一定要是str,不能是int”,什么意思呢?
這就要說說python中的數據類型了:
先說變量和常量的概念:變量的概念我們已經很清楚了,是指可以表示不同內容的符號,是可變的量。常量的概念和變量對應,表示永遠不會改變的量,比如1永遠是1,不可能是2,字符串‘abc’也永遠是‘abc’,這些不可改變的量都可以稱為常量。
變量也好、常量也罷,其表示的都是一個數據,數據與數據是不同的,比如1、2這些是整數;1.1、3.14這些是小數;-2、-12這些是負數等,這就有了類別。對應到程序中,就是數據類型的概念了,比如a = 2,此時變量a的類型是**整數類型**,簡稱整型,也就是上面報錯信息中提到的**int**;而**str**表示的是**字符串類型**,如果b = 'abc',那么此時變量b的數據類型就是字符串類型。
> 墨博士提醒:在python中,變量的數據類型是可以變化的,比如:
>```
>a = 2
>print(a)
>a = 'abc'
>print(a)
>```
>運行結果為:
>```
>2
>abc
>```
>這里第1行中a是int類型,第2行中a就變成str類型了。
回到上面代碼的報錯上,這里報錯的原因是:'a + b = '是一個字符串,而(a+b)是兩個int類型做了數學的加運算,兩個int類型的數據相加,得到的結果還是int類型。Python中str類型之間可以使用+號拼接,而str類型和int類型是不能通過+號拼接的。
小墨:那如果想要拼接怎么辦?
墨博士:想要拼接,需要將a+b的結果由int類型轉為str類型,這使用str()來實現。修改代碼如下:
```
print('a + b = ' + str(a + b))
```
輸出結果為:
```
a + b = 5
```
同理,我們也可以在字符串上加上int(),讓字符串轉為整數,但前提是這個字符串的字符組成本身就是整數。比如:
```
a = '2'
print(int(a) + 10)
```
輸出結果為:
```
12
```
上述程序中的第一行中的2雖然是一個整數,但是加上單引號之后就變成了字符串類型的2了,此時賦值給a,a也就是字符串類型了。如果字符串類型的a和整數類型的10直接通過+號拼接,結果還是會報類似上圖2.7的錯誤。想相加的話可以通過int()將a轉為整數類型,再相加就是數學運行了,運算結果為12。你理解了嗎小墨?
小墨:嗯理解了,str()能將整數類型轉為字符串類型,int()能將字符串類型的數字轉為整數類型的。
## 2.6 本章小結
墨博士總結:本章你的收獲非常多,無論是理論性還是實踐性的東西都涉及了。你更加熟悉了IDLE的基本用法,學會了輸入輸出的使用、變量的使用、理解了使用變量的好處、掌握了整數類型和字符串類型的區別、str()和int()的使用,還解決了第一個bug。毫不夸張的說,你已經入門Python了。
不過你的Python之路才剛剛開始,后面需要學習的東西還很多,好好休息,然后讓我們繼續前進吧!