跳轉到內容

Think Python/變數、表示式和語句

來自華夏公益教科書

值和型別

[edit | edit source]

是程式操作的基本事物之一,例如字母或數字。我們到目前為止見過的值包括1, 2,以及 'Hello, World!'

這些值屬於不同的型別2是一個整數,而 'Hello, World!' 是一個字串,之所以稱為字串,是因為它包含一個字母“字串”。您可以(以及直譯器)透過它們是否包含在引號中來識別字符串。

print 語句也適用於整數。

>>> print (4)
4

如果您不確定某個值的型別,直譯器可以告訴您。

>>> type('Hello, World!')
<type 'str'>
>>> type(17)
<type 'int'>

不出所料,字串屬於型別str,而整數屬於型別int。不太明顯的是,帶小數點的數字屬於一種稱為float的型別,因為這些數字以一種稱為浮點數的格式表示。

>>> type(3.2)
<type 'float'>

那麼像 '17''3.2' 這樣的值呢?它們看起來像數字,但它們包含在像字串一樣的引號中。

>>> type('17')
<type 'str'>
>>> type('3.2')
<type 'str'>

它們是字串。

當您輸入一個大整數時,您可能會傾向於在三位數的組之間使用逗號,例如1,000,000。這在 Python 中不是一個合法的整數,但它是合法的

>>> print 1,000,000
1 0 0

嗯,這完全不是我們預期的!Python 將1,000,000解釋為一個以逗號分隔的整數序列,它以空格分隔的形式打印出來。

這是我們見過的第一個語義錯誤示例:程式碼在沒有產生錯誤訊息的情況下執行,但它並沒有做“正確”的事情。

變數

[edit | edit source]

程式語言最強大的功能之一是能夠操作變數。變數是引用值的名稱。

賦值語句建立新的變數並賦予它們值

>>> message = 'And now for something completely different'
>>> n = 17
>>> pi = 3.1415926535897931

此示例進行了三個賦值。第一個將字串賦值給一個名為message的新變數;第二個將整數17賦值給n;第三個將 π 的(近似)值賦值給pi.

。在紙上表示變數的一種常見方法是寫下名稱,並用箭頭指向變數的值。這種圖被稱為狀態圖,因為它顯示了每個變數的狀態(將其視為變數的心態)。此圖顯示了上一個示例的結果

message 'And now for something completely different'
n 17
pi 3.1415926535897931

要顯示變數的值,可以使用 print 語句

>>> print n
17
>>> print pi
3.14159265359

變數的型別是它引用的值的型別。

>>> type(message)
<type 'str'>
>>> type(n)
<type 'int'>
>>> type(pi)
<type 'float'>

練習 1

[edit | edit source]

如果您輸入一個以零開頭的整數,您可能會得到一個令人困惑的錯誤

>>> zipcode = 02492
                 ^
SyntaxError: invalid token

其他數字似乎可以工作,但結果很奇怪

>>> zipcode = 02132
>>> print zipcode
1114

你能弄清楚發生了什麼事嗎?提示:列印值 01010010001000

變數名和關鍵字

[edit | edit source]

程式設計師通常會選擇對變數有意義的名稱——它們記錄了變數的使用目的。

變數名可以任意長。它們可以包含字母和數字,但必須以字母開頭。使用大寫字母是合法的,但最好以小寫字母開頭變數名(您將在後面看到原因)。

下劃線字元 (_) 可以出現在名稱中。它通常用於包含多個單詞的名稱,例如 my_nameairspeed_of_unladen_swallow

如果您給變數一個非法名稱,您將得到一個語法錯誤

>>> 76trombones = 'big parade'
SyntaxError: invalid syntax
>>> more@ = 1000000
SyntaxError: invalid syntax
>>> class = 'Advanced Theoretical Zymurgy'
SyntaxError: invalid syntax

76trombones是非法的,因為它沒有以字母開頭。more@是非法的,因為它包含一個非法字元,@。但class?

有什麼問題呢?事實證明class是 Python 的關鍵字之一。直譯器使用關鍵字來識別程式的結構,它們不能用作變數名。

Python 有 31 個關鍵字

以及 del from not while
as elif global or with
assert else if pass yield
break except import print
class exec in raise
continue finally is return
def for lambda try

您可能需要將此列表隨時備用。如果直譯器抱怨您的變數名稱之一,而您不知道原因,請檢視它是否在此列表中。

如果您在瞭解 Python 的文字編輯器中編寫程式碼,您可能會發現它可以輕鬆地讓您發現此類關鍵字衝突,因為它以與普通變數不同的顏色顯示關鍵字。此功能稱為語法高亮,大多數程式設計師都認為它是必不可少的。本書為其示例程式碼使用語法高亮,因此在以下示例中

ok_variable = 42
yield = 42

您可以看到 yield 被識別為關鍵字,而不是普通變數,因為它被塗成綠色。

語句

[edit | edit source]

語句是 Python 直譯器可以執行的程式碼單元。我們已經看到了兩種語句:print 和賦值。

當您在互動模式下鍵入語句時,直譯器會執行它並顯示結果(如果有)。

指令碼通常包含一系列語句。如果有多個語句,則結果將隨著語句執行而逐一齣現。

例如,指令碼

print 1
x = 2
print x

產生以下輸出

1
2

賦值語句不會產生輸出。

運算子和運算元

[edit | edit source]

運算子是代表計算(如加法和乘法)的特殊符號。運算子應用到的值稱為運算元

運算子+, -, *, /以及**執行加法、減法、乘法、除法和求冪,如以下示例所示

20+32   hour-1   hour*60+minute   minute/60   5**2   (5+9)*(15-7)

在其他一些語言中,^ 用於求冪,但在 Python 中,它是一個稱為異或的按位運算子。我不會在本手冊中介紹按位運算子,但您可以在以下地址閱讀相關內容:wiki.python.org/moin/BitwiseOperators.

除法運算子可能不會按預期執行

>>> minute = 59
>>> minute/60
0

的值minute是 59,在傳統的算術運算中,59 除以 60 等於 0.98333,而不是 0。造成這種差異的原因是 Python 執行的是向下取整除法[1]

當兩個運算元都是整數時,結果也是整數;向下取整除法會將小數部分截斷,因此在本例中,它向下取整為零。

如果運算元之一是浮點數,Python 將執行浮點數除法,結果為一個float:

>>> minute/60.0
0.98333333333333328

表示式

[edit | edit source]

一個表示式是值、變數和運算子的組合。一個值本身被認為是一個表示式,變數也是,因此以下都是合法表示式(假設變數x已經被賦值了)

17
x
x + 17

如果你在互動模式下輸入一個表示式,直譯器會計算它並顯示結果

>>> 1 + 1
2

但在指令碼中,一個表示式本身不會做任何事情!這是初學者常犯的錯誤。

練習 2

[edit | edit source]

在 Python 直譯器中輸入以下語句,看看它們做了什麼

5
x = 5
x + 1

現在將相同的語句放到指令碼中並執行它。輸出是什麼?透過將每個表示式轉換為 print 語句來修改指令碼,然後再次執行它。

運算順序

[edit | edit source]

當一個表示式中出現多個運算子時,運算順序取決於優先順序規則。對於數學運算子,Python 遵循數學慣例。首字母縮略詞PEMDAS是記憶規則的一種有用方法

  • Parentheses 具有最高優先順序,可用於強制表示式按您想要的順序計算。由於括號內的表示式首先計算,因此2 * (3-1)為 4,而(1+1)**(5-2)為 8。您也可以使用括號使表示式更易於閱讀,例如(minute * 100) / 60,即使它不改變結果。
  • Exponentiation 具有次高優先順序,因此2**1+1為 3,而不是 4,並且3*1**3為 3,而不是 27。
  • Multiplication 和 Division 具有相同的優先順序,高於 Addition 和 Subtraction,它們也具有相同的優先順序。所以2*3-1為 5,而不是 4,並且6+4/2為 8,而不是 5。
  • 具有相同優先順序的運算子從左到右計算。因此在表示式degrees / 2 * pi中,除法首先發生,結果乘以pi。要除以 2 π,您可以重新排序運算元或使用括號。

字串操作

[edit | edit source]

一般來說,您不能對字串執行數學運算,即使字串看起來像數字,因此以下操作是非法的

'2'-'1'    'eggs'/'easy'    'third'*'a charm'

the+運算子與字串一起使用,但它可能不會按預期執行:它執行串聯,這意味著將字串首尾相連。例如

first = 'throat'
second = 'warbler'
print first + second

該程式的輸出是throatwarbler.

the*運算子也適用於字串;它執行重複。例如,’Spam’*3'SpamSpamSpam'。如果運算元之一是字串,另一個必須是整數。

這種使用+以及*有意義,因為它與加法和乘法類似。就像4*3等同於4+4+4一樣,我們希望 'Spam'*3'Spam'+'Spam'+'Spam' 相同,它確實相同。另一方面,字串串聯和重複與整數加法和乘法有一個顯著的區別。你能想到加法具有的而字串串聯不具有的屬性嗎?

註釋

[edit | edit source]

隨著程式變得越來越大、越來越複雜,它們也越來越難讀。形式語言很密集,通常很難檢視一段程式碼並弄清楚它在做什麼,或者為什麼。

因此,最好在程式中添加註釋,以用自然語言解釋程式在做什麼。這些註釋稱為註釋,它們以#符號開頭

# compute the percentage of the hour that has elapsed
percentage = (minute * 100) / 60

在這種情況下,註釋出現在一行中。您也可以將註釋放在一行的末尾

percentage = (minute * 100) / 60     # percentage of an hour

#到行尾的所有內容都會被忽略——它不會對程式產生任何影響。

註釋在記錄程式碼的非明顯特徵時最有用。可以合理地假設讀者可以弄清楚程式碼做什麼;解釋為什麼更有用。

此註釋與程式碼冗餘且無用

v = 5     # assign 5 to v

此註釋包含程式碼中沒有的有用資訊

v = 5     # velocity in meters/second.

好的變數名可以減少對註釋的需要,但過長的名稱會使複雜的表示式難以閱讀,因此存在權衡。

除錯

[edit | edit source]

此時,您最有可能遇到的語法錯誤是無效的變數名,例如class以及yield,它們是關鍵字,或者 odd~jobUS$,它們包含無效字元。

如果您在變數名中放一個空格,Python 會認為它是兩個沒有運算子的運算元

>>> bad name = 5
SyntaxError: invalid syntax

對於語法錯誤,錯誤訊息並沒有多大幫助。最常見的錯誤訊息是SyntaxError: invalid syntax以及SyntaxError: invalid token,它們都不太具有資訊量。

您最有可能遇到的執行時錯誤是“使用前定義”;也就是說,在為變數賦值之前嘗試使用它。如果拼錯了變數名,就會發生這種情況

>>> principal = 327.68
>>> interest = principle * rate
NameError: name 'principle' is not defined

變數名區分大小寫,因此LaTeXlatex.

不同

>>> 1.0 / 2.0 * pi

此時,語義錯誤最有可能的原因是運算順序。例如,要計算 1/2 π,您可能會嘗試編寫

但除法首先發生,因此您將得到 π / 2,它與 1/2 π 不一樣!Python 無法知道您想要寫什麼,因此在這種情況下您不會收到錯誤訊息;您只會得到錯誤的答案。

詞彙表
[edit | edit source]
資料的基本單元之一,例如數字或字串,程式對其進行操作。
型別int值的類別。到目前為止,我們看到的型別是整數(型別float),浮點數(型別str).
),和字串(型別
整數
表示整數的型別。
浮點數
表示帶小數部分的數字的型別。
字串
表示字元序列的型別。
變數
指代值的名稱。
語句
代表命令或操作的程式碼部分。到目前為止,我們看到的語句是賦值和 print 語句。
賦值
將值賦給變數的語句。
狀態圖
一組變數及其所指值的圖形表示。
關鍵字if, def編譯器用來解析程式的保留字;您不能使用諸如while
之類的關鍵字作為變數名。
運算子
表示簡單計算的特殊符號,例如加法、乘法或字串串聯。
運算元
運算子作用的值之一。
向下取整除法
將兩個數字相除並砍掉小數部分的操作。
表示式
表示單個結果值的變數、運算子和值的組合。
計算
透過按順序執行運算來簡化表示式以生成單個值。
優先順序規則
控制包含多個運算子和運算元的表示式計算順序的規則集。
串聯
將兩個運算元首尾相連。
註釋

程式中的資訊,意在供其他程式設計師(或閱讀原始碼的任何人)使用,對程式執行沒有影響。

練習

[edit | edit source]

練習 3

[edit | edit source]

width = 17
height = 12.0
delimiter = '.'

假設我們執行以下賦值語句

width/2
width/2.0
height/3
1 + 2 * 5
delimiter * 5

對於以下每個表示式,寫出表示式的值和型別(表示式的值的型別)。

使用 Python 直譯器檢查您的答案。

練習 4

[edit | edit source]

  • 半徑為 的球體的體積為 4/3 π 。半徑為 5 的球體的體積是多少?提示:392.6 是錯誤的!
  • 假設一本圖書的定價為 24.95 美元,但書店可以享受 40% 的折扣。第一本圖書的運費為 3 美元,每增加一本圖書運費為 75 美分。60 本圖書的批發價是多少?
  • 如果我早上 6:52 離開家,以輕鬆的速度(每英里 8:15)跑 1 英里,然後以中速(每英里 7:12)跑 3 英里,最後再以輕鬆的速度跑 1 英里,我幾點回到家吃早餐?
  1. 在 Python 3.0 中,此除法的結果為 float。新運算子 // 執行整數除法。
華夏公益教科書