我們來嘗試一些簡單的 Python 命令。啟動解釋器然后等待主提示符?>>>?出現(不需要很久)。
### 3.1.1\. 數字
解釋器的表示就像一個簡單的計算器:可以向其錄入一些表達式,它會給出返回值。表達式語法很直白:運算符?+,?-,?*?和?/?與其它語言一樣(例如:Pascal 或 C);括號用于分組。例如:
~~~
>>> 2+2
4
>>> # This is a comment
... 2+2
4
>>> 2+2 # and a comment on the same line as code
4
>>> (50-5*6)/4
5.0
>>> 8/5 # Fractions aren't lost when dividing integers
1.6
~~~
注意:有時你可能會得到不同的結果;浮點數在不同機器上的運算結果可能是不同的。后面我們將對控制浮點數輸出的顯示結果做更多說明;這里我們看到的僅是有效的顯示,并非我們能得到的可讀性更好的結果。
對整數做除法運算并想去除小數部分取得整數結果時,可以使用另外一個運算符,//:
~~~
>>> # Integer division returns the floor:
... 7//3
2
>>> 7//-3
-3
~~~
等號(?'='?)用于給變量賦值:
~~~
>>> width = 20
>>> height = 5*9
>>> width * height
900
~~~
一個值可以同時賦給幾個變量:
~~~
>>> x = y = z = 0 # Zero x, y and z
>>> x
0
>>> y
0
>>> z
0
~~~
變量在使用前必須“定義”(賦值),否則會出錯:
~~~
>>> # try to access an undefined variable
... n
Traceback (most recent call last):
File "", line 1, in
NameError: name 'n' is not defined
~~~
浮點數有完整的支持;與整型混合計算時會自動轉為浮點數:
~~~
>>> 3 * 3.75 / 1.5
7.5
>>> 7.0 / 2
3.5
~~~
復數也得到支持;帶有后綴?j?或?J?就被視為虛數。帶有非零實部的復數寫為?(real+imagj),或者可以用?complex(real,?imag)?函數創建。
~~~
>>> 1j * 1J
(-1+0j)
>>> 1j * complex(0, 1)
(-1+0j)
>>> 3+1j*3
(3+3j)
>>> (3+1j)*3
(9+3j)
>>> (1+2j)/(1+1j)
(1.5+0.5j)
~~~
復數的實部和虛部總是記為兩個浮點數。要從復數 z 中提取實部和虛部,使用?z.real?和?z.imag:
~~~
>>> a=1.5+0.5j
>>> a.real
1.5
>>> a.imag
0.5
~~~
浮點數和整數之間的轉換函數(?float()?和?int()?以及?long()?)不能用于復數。沒有什么正確方法可以把一個復數轉成一個實數。函數?abs(z)?用于獲取其模(浮點數)或?z.real?獲取其實部:
~~~
>>> a=3.0+4.0j
>>> float(a)
Traceback (most recent call last):
File "", line 1, in ?
TypeError: can't convert complex to float; use abs(z)
>>> a.real
3.0
>>> a.imag
4.0
>>> abs(a) # sqrt(a.real**2 + a.imag**2)
5.0
~~~
交互模式中,最近一個表達式的值賦給變量?_?。這樣我們就可以把它當作一個桌面計算器,很方便的用于連續計算,例如:
~~~
>>> tax = 12.5 / 100
>>> price = 100.50
>>> price * tax
12.5625
>>> price + _
113.0625
>>> round(_, 2)
113.06
~~~
此變量對于用戶是只讀的。不要嘗試給它賦值 —— 你只會創建一個獨立的同名局部變量,它屏蔽了系統內置變量的魔術效果.
### 3.1.2\. 字符串
相比數值,Python 也提供了可以通過幾種不同方式傳遞的字符串。它們可以用單引號或雙引號標識:
~~~
>>> 'spam eggs'
'spam eggs'
>>> 'doesn\'t'
"doesn't"
>>> "doesn't"
"doesn't"
>>> '"Yes," he said.'
'"Yes," he said.'
>>> "\"Yes,\" he said."
'"Yes," he said.'
>>> '"Isn\'t," she said.'
'"Isn\'t," she said.'
~~~
Python 解釋器按照字符串被輸入的方式打印字符串結果:為了顯示準確的值,字符串包含在成對的引號中,引號和其他特殊字符要用反斜線( \ )轉譯。 如果字符串只包含單引號( ‘ )而沒有雙引號( ” )就可以用雙引號( ” )包圍,反之用單引號( ‘ )包圍。再強調一下,print?函數可以生成可讀性更好的輸出。
字符串文本有幾種方法分行。可以使用反斜杠為行結尾的連續字符串,它表示下一行在邏輯上是本行的后續內容:
~~~
hello = "This is a rather long string containing\n\
several lines of text just as you would do in C.\n\
Note that whitespace at the beginning of the line is\
significant."
print(hello)
~~~
需要注意的是,還是需要在字符串中寫入?\n?—— 結尾的反斜杠會被忽略。前例會打印為如下形式:
~~~
This is a rather long string containing
several lines of text just as you would do in C.
Note that whitespace at the beginning of the line is significant.
~~~
另外,字符串可以標識在一對兒三引號中:"""?或?'''。三引號中,不需要行屬轉義,它們已經包含在字符串中:
~~~
print("""\
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
""")
~~~
得到如下輸出:
~~~
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
~~~
如果我們生成一個“原始”字符串,\n?序列不會被轉義,而且行尾的反斜杠,源碼中的換行符,都成為字符串中的一部分數據,因此下例:
~~~
hello = r"This is a rather long string containing\n\
several lines of text much as you would do in C."
print(hello)
~~~
會打印:
~~~
This is a rather long string containing\n\
several lines of text much as you would do in C.
~~~
字符串可以由?+?操作符連接(粘到一起),可以由?*?重復:
~~~
>>> word = 'Help' + 'A'
>>> word
'HelpA'
>>> ' + word*5 + '>'
''
~~~
相鄰的兩個字符串文本自動連接在一起,前面那行代碼也可以寫為?word?='Help'?'A';它只用于兩個字符串文本,不能用于字符串表達式:
~~~
>>> 'str' 'ing' #
'string'
>>> 'str'.strip() + 'ing' #
'string'
>>> 'str'.strip() 'ing' #
File "", line 1, in ?
'str'.strip() 'ing'
^
SyntaxError: invalid syntax
~~~
字符串也可以被截取(檢索)。類似于 C,字符串的第一個字符索引為 0。沒有獨立的字符類型,字符就是長度為 1 的字符串。類似 Icon,可以用?_切片標注_?法截取字符串:由兩個索引分割的復本。
~~~
>>> word[4]
'A'
>>> word[0:2]
'He'
>>> word[2:4]
'lp'
~~~
索引切片可以有默認值,切片時,忽略第一個索引的話,默認為 0,忽略第二個索引,默認為字符串的長度:
~~~
>>> word[:2] # The first two characters
'He'
>>> word[2:] # Everything except the first two characters
'lpA'
~~~
不同于 C 字符串,Python 字符串不可變。向字符串文本的某一個索引賦值會引發錯誤:
~~~
>>> word[0] = 'x'
Traceback (most recent call last):
File "", line 1, in ?
TypeError: 'str' object does not support item assignment
>>> word[:1] = 'Splat'
Traceback (most recent call last):
File "", line 1, in ?
TypeError: 'str' object does not support slice assignment
~~~
不過,組合文本內容生成一個新文本簡單而高效:
~~~
>>> 'x' + word[1:]
'xelpA'
>>> 'Splat' + word[4]
'SplatA'
~~~
切片操作有個有用的不變性:s[:i]?+?s[i:]?等于?s:
~~~
>>> word[:2] + word[2:]
'HelpA'
>>> word[:3] + word[3:]
'HelpA'
~~~
Python 能夠優雅的處理那些沒有意義的切片索引:一個過大的索引值(即下標值大于字符串實際長度)將被字符串實際長度所代替,當上邊界比下邊界大時(即切片左值大于右值)就返回空字符串:
~~~
>>> word[1:100]
'elpA'
>>> word[10:]
''
>>> word[2:1]
''
~~~
索引也可以是負數,這將導致從右邊開始計算。例如:
~~~
>>> word[-1] # The last character
'A'
>>> word[-2] # The last-but-one character
'p'
>>> word[-2:] # The last two characters
'pA'
>>> word[:-2] # Everything except the last two characters
'Hel'
~~~
請注意 -0 實際上就是 0,所以它不會導致從右邊開始計算!
~~~
>>> word[-0] # (since -0 equals 0)
'H'
~~~
負索引切片越界會被截斷,不要嘗試將它用于單元素(非切片)檢索:
~~~
>>> word[-100:]
'HelpA'
>>> word[-10] # error
Traceback (most recent call last):
File "", line 1, in ?
IndexError: string index out of range
~~~
有個辦法可以很容易地記住切片的工作方式:切片時的索引是在兩個字符?_之間_?。左邊第一個字符的索引為0,而長度為?_n_?的字符串其最后一個字符的右界索引為?_n_。例如:
+---+---+---+---+---+
| H | e | l | p | A |
+---+---+---+---+---+
0 1 2 3 4 5
-5 -4 -3 -2 -1
文本中的第一行數字給出字符串中的索引點 0...5。第二行給出相應的負索引。切片是從?_i_?到?_j_?兩個數值標示的邊界之間的所有字符。
對于非負索引,如果上下都在邊界內,切片長度與索引不同。例如,word[1:3]?是 2。
內置函數?len()?返回字符串長度:
~~~
>>> s = 'supercalifragilisticexpialidocious'
>>> len(s)
34
~~~
### 3.1.3\. 關于 Unicode
從 Python 3.0 開始所有的字符串都支持 Unicode(參考?[http://www.unicode.org](http://www.unicode.org/)?)。
Unicode 的先進之處在于為每一種現代或古代使用的文字系統中出現的每一個字符都提供了統一的序列號。之前,文字系統中的字符只能有 256 種可能的順序。通過代碼頁分界映射。文本綁定到映射文字系統的代碼頁。這在軟件國際化的時候尤其麻煩(通常寫作?i18n?——?'i'?+ 18 個字符 +'n'?)。Unicode 解決了為所有的文字系統設置一個獨立代碼頁的難題。
如果想在字符串中包含特殊字符,你可以使用Python的?_Unicode_Escape_?編碼方式。下面的例子展示了如何這樣做:
~~~
>>> 'Hello\u0020World !'
'Hello World !'
~~~
轉碼序列?\u0020?表示在指定位置插入編碼為 0x0020 的 Unicode 字符(空格)。
其他字符就像 Unicode 編碼一樣被直接解釋為對應的編碼值。 如果你有在許多西方國家使用的標準 Latin-1 編碼的字符串,你會發現編碼小于 256 的 Unicode 字符和在 Latin-1 編碼中的一樣。
除了這些標準編碼,Python 還提供了一整套基于其他已知編碼創建 Unicode 字符串的方法。
字符串對象提供了一個?encode()?方法用以將字符串轉換成特定編碼的字節序列,它接收一個小寫的編碼名稱作為參數:
~~~
>>> "?pfel".encode('utf-8')
b'\xc3\x84pfel'
~~~
### 3.1.4\. 列表
Python 有幾個?_復合_?數據類型,用于表示其它的值。最通用的是?_list_?(列表) ,它可以寫作中括號之間的一列逗號分隔的值。列表的元素不必是同一類型:
~~~
>>> a = ['spam', 'eggs', 100, 1234]
>>> a
['spam', 'eggs', 100, 1234]
~~~
就像字符串索引,列表從 0 開始檢索。列表可以被切片和連接:
~~~
>>> a[0]
'spam'
>>> a[3]
1234
>>> a[-2]
100
>>> a[1:-1]
['eggs', 100]
>>> a[:2] + ['bacon', 2*2]
['spam', 'eggs', 'bacon', 4]
>>> 3*a[:3] + ['Boo!']
['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boo!']
~~~
所有的切片操作都會返回新的列表,包含求得的元素。這意味著以下的切片操作返回列表?_a_?的一個淺拷貝的副本:
~~~
>>> a[:]
['spam', 'eggs', 100, 1234]
~~~
不像?_不可變的_?字符串,列表允許修改元素:
~~~
>>> a
['spam', 'eggs', 100, 1234]
>>> a[2] = a[2] + 23
>>> a
['spam', 'eggs', 123, 1234]
~~~
也可以對切片賦值,此操作可以改變列表的尺寸,或清空它:
~~~
>>> # Replace some items:
... a[0:2] = [1, 12]
>>> a
[1, 12, 123, 1234]
>>> # Remove some:
... a[0:2] = []
>>> a
[123, 1234]
>>> # Insert some:
... a[1:1] = ['bletch', 'xyzzy']
>>> a
[123, 'bletch', 'xyzzy', 1234]
>>> # Insert (a copy of) itself at the beginning
>>> a[:0] = a
>>> a
[123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]
>>> # Clear the list: replace all items with an empty list
>>> a[:] = []
>>> a
[]
~~~
內置函數?len()?同樣適用于列表:
~~~
>>> a = ['a', 'b', 'c', 'd']
>>> len(a)
4
~~~
允許嵌套列表(創建一個包含其它列表的列表),例如:
~~~
>>> q = [2, 3]
>>> p = [1, q, 4]
>>> len(p)
3
>>> p[1]
[2, 3]
>>> p[1][0]
2
~~~
你可以在列表末尾添加內容:
~~~
>>> p[1].append('xtra')
>>> p
[1, [2, 3, 'xtra'], 4]
>>> q
[2, 3, 'xtra']
~~~
注意最后一個例子中,?p[1]?和?q?實際上指向同一個對象!我們會在后面的?_object semantics_?中繼續討論。
- Python 入門指南
- 1. 開胃菜
- 2. 使用 Python 解釋器
- 2.1. 調用 Python 解釋器
- 2.2. 解釋器及其環境
- 3. Python 簡介
- 3.1. 將 Python 當做計算器
- 3.2. 編程的第一步
- 4. 深入 Python 流程控制
- 4.1. if 語句
- 4.2. for 語句
- 4.3. range() 函數
- 4.4. break 和 continue 語句, 以及循環中的 else 子句
- 4.5. pass 語句
- 4.6. 定義函數
- 4.7. 深入 Python 函數定義
- 4.8. 插曲:編碼風格
- 5. 數據結構
- 5.1. 關于列表更多的內容
- 5.2. del 語句
- 5.3. 元組和序列
- 5.4. 集合
- 5.5. 字典
- 5.6. 循環技巧
- 5.7. 深入條件控制
- 5.8. 比較序列和其它類型
- 6. 模塊
- 6.1. 深入模塊
- 6.2. 標準模塊
- 6.3. dir() 函數
- 6.4. 包
- 7. 輸入和輸出
- 7.1. 格式化輸出
- 7.2. 文件讀寫
- 8. 錯誤和異常
- 8.1. 語法錯誤
- 8.2. 異常
- 8.3. 異常處理
- 8.4. 拋出異常
- 8.5. 用戶自定義異常
- 8.6. 定義清理行為
- 8.7. 預定義清理行為
- 9. 類
- 9.1. 術語相關
- 9.2. Python 作用域和命名空間
- 9.3. 初識類
- 9.4. 一些說明
- 9.5. 繼承
- 9.6. 私有變量
- 9.7. 補充
- 9.8. 異常也是類
- 9.9. 迭代器
- 9.10. 生成器
- 9.11. 生成器表達式
- 10. Python 標準庫概覽
- 10.1. 操作系統接口
- 10.2. 文件通配符
- 10.3. 命令行參數
- 10.4. 錯誤輸出重定向和程序終止
- 10.5. 字符串正則匹配
- 10.6. 數學
- 10.7. 互聯網訪問
- 10.8. 日期和時間
- 10.9. 數據壓縮
- 10.10. 性能度量
- 10.11. 質量控制
- 10.12. “瑞士軍刀”
- 11. 標準庫瀏覽 – Part II
- 11.1. 輸出格式
- 11.2. 模板
- 11.3. 使用二進制數據記錄布局
- 11.4. 多線程
- 11.5. 日志
- 11.6. 弱引用
- 11.7. 列表工具
- 11.8. 十進制浮點數算法
- 12. 接下來?
- 13. 交互式輸入行編輯歷史回溯
- 13.1. 行編輯
- 13.2. 歷史回溯
- 13.3. 快捷鍵綁定
- 13.4. 其它交互式解釋器
- 14. 浮點數算法:爭議和限制
- 14.1. 表達錯誤
- 15. 附錄
- 15.1. 交互模式