1、Python program structures.
(1) Programs are composed of modules.
(2) Modules contain statements.
(3) Statements contain expressions.
(4) Expressions create and process objects.
2、Python built-in Types:
,List是指沒有重複元素的collection;Dictionary是指key-value這樣儲存的集合;Tuple應該就是collection吧,這個不是很清楚,後面會詳細講;本章重點講述的是Number。
3、Numbers,首先看一張圖,這是Python支援的Number列表:
由可以看到,Python首先支援integer,這裡需要注意的是Python中的integer就相當於C中的long,也就是說,資料寬度至少 是32Bit;第二,Python支援沒有限制的Long integers,這種integer在書寫的時候要在後面加上一個 L 或 l 來表示這是一個long型的integer,如果沒有加的話也不要緊,因為如果Python在計算的時候發現溢出了(overflow),她就會自動將溢 出的integer聲明成Long型的,然後繼續,所以,不加也無所謂(Attention:在Python 2.2之前的版本中,必須加 L 或 l,換句話說,2.2之前的Python不會在overflow的時候自動將integer變成long);第三,Python支援Float,她的 float就相當於C中的double了;第四,Python還支援八進位和十六進位標記法,這和C一樣(八進位以0打頭,十六進位以 0x 或 0X 打頭);最後,Python還支援複數,這是C沒有的。
4、Python支援的Expression,注意,這個表中列的不光是針對Number的Expression,基本上Python所支援的expression都在這裡了(包括邏輯運算):
圖上可以看到,大部分的operator都可以理解,有些沒見過的將在將來講述。
5、書中還講述了什麼operator優先順序、括弧的作用以及類型強制轉換規則等,這些都學過,不贅述了。
6、Python也支援operator overload,比如 + ,操作兩個Number的時候就是做加法,操作兩個string的時候就是做字串串連,當然,我們也可以自己寫代碼重載operator,實現自己的邏輯。
7、舉例。Python中的變數不需要聲明,直接賦值即可,以 # 開頭的都是注釋,如:
% python
>>> a = 3 # Name created
>>> b = 4
這些操作鬼都看的明白:
>>> a + 1, a - 1 # Addition (3+1), subtraction (3-1)
(4, 2)
>>> b * 3, b / 2 # Multiplication (4*3), division (4/2)
(12, 2)
>>> a % 2, b ** 2 # Modulus (remainder), power
(1, 16)
>>> 2 + 4.0, 2.0 ** b # Mixed-type conversions
(6.0, 16.0)
這個例子就有點意思了:
>>> b / (2.0 + a) # Auto echo output: more digits
0.80000000000000004
>>> print b / (2.0 + a) # print rounds off digits.
0.8
這裡可以看到,print有規整化輸出的功用。
關于格式化輸出的例子,這裡還有:
>>> num = 1 / 3.0
>>> num # Echoes
0.33333333333333331
>>> print num # Print rounds
0.333333333333
>>> "%e" % num # String formatting
'3.333333e-001'
>>> "%2.2f" % num # String formatting
'0.33'
這裡最後用到的就是格式化字串的方法了,看到了吧,用法就是 "格式化字串" % "變數",這樣,變數的輸出就被格式化了。
8、除法。Python的除法有點意思,分為 / 和 // 兩個操作符。/ 符號如果不做特殊處理,那麼,他會根據運算元的類型給出結果,比如,一個整數 / 一個整數,那麼,就算除下來有小數,/ 符號也會將其截斷,因為 / 認為結果也要是integer;如果是 float / float,那麼,結果就有小數,也是float。相比而言,// 就是純純正正的除法取整了,也就是說,不管運算元是什麼類型,採用 // 操作符,出來的結果肯定是取整後的整數。在Python的書中,把 / 操作符稱為classic division,把 // 稱為Floor division。此外,書中還提到了True division,這是什麼意思呢?這就是純正的除法了,也就是說,不管運算元是什麼類型,除下來結果該是多少就是多少,不做任何處理,比如兩個整數相 除,除下來結果是整的就是整的,是有小數的就是有小數的,這就是True division。書中說了,在將來的Python 3.0裡面,/ 符號就要變成 True division 而不是classic division,而 // 不變;在目前版本的Python中,其實已經支援True division,只不過要做一下聲明:>>> from __future__ import division,做了這個聲明後,再使用 / 操作符就是做True division了,不做這個聲明用 / 操作符,就是做classic division。
9、有關bit操作和long操作就不講了,簡單。
10、八進位、十進位和十六進位。八進位以0開頭,十六進位以 0x 或 0X 開頭。用oct、hex這兩個built-in的函數可以將十進位變成八進位和十六進位,如下:
>>> oct(64), hex(64), hex(255)
('0100', '0x40', '0xff')
int函數可以將一個字串變成一個整數,這個函數有第二個參數,就可以指定將字串變成何種進位的數,如:
>>> int('0100'), int('0100', , int('0x40', 16)
(100, 64, 64)
eval函數和BASH中的eval一樣,可以將參數做為一句Python的代碼並加以執行,如:
>>> eval('100'), eval('0100'), eval('0x40')
(100, 64, 64)
最後,我們可以使用字串的格式化功能來將不同進位的數字格式化成字串,如:
>>> "%o %x %X" % (64, 64, 255)
'100 40 FF'
11、Python中還有一些包可以用數字方面的運算,如math包:
>>> import math
>>> math.pi, math.e
(3.1415926535897931, 2.7182818284590451)
>>> math.sin(2 * math.pi / 180)
0.034899496702500969
>>> abs(-42), 2**4, pow(2, 4)
(42, 16, 16)
>>> int(2.567), round(2.567), round(2.567, 2)
(2, 3.0, 2.5699999999999998)
這裡看到,abs和pow不是math包中的函數,而是標準built-in的函數,最後的round(2.567, 2)指保留兩位小數,如果用print round(2.567, 2)的話,就會輸出2.57了。
12、有一些Python的擴充包可以做更進階的數字運算,比如NumPy module,她就可以做矩陣運算等等,NumPy module不在Python中,需要獨立下載和安裝。
13、本章的最後一節解釋了Python的一些原理。為什麼Python中的變數不需要聲明?名字不需要聲明,甚至類型都無需聲明。這是因為Python將任何變數都看成是對一個object的引用,變數的具體類型要等到執行的時候才會被確定,這就是原因。
14、這裡是針對上面一些話的解釋。比如,考慮 a = 3 這個expression,在Python內部,a是這樣被定義的(圖一):
看到了嗎?a只是一個name,Python會分配一塊記憶體,用來儲存3,然後將a定義為指向3的一個引用。我們可以把這裡的引用想象成C中的 void * ,所以,a不需要類型,3也不需要類型,只是一個object,然後a指向3,僅此而已。
15、需要注意的是,Python為了節省記憶體,會做一個share object name的動作,就是將值一樣的變數都指向一個object,比如考慮這樣的代碼:
>>> a = 3
>>> b = a
在Python中,是醬紫的(圖2):
看到了嗎?a和b指向一個object,如果:
>>> a = 3
>>> b = a
>>> a = 'spam'
那麼,就會變成醬紫(圖3):
16、上面的情況是沒有問題的,這是因為a和b兩個變數指向的object本身是不可改變的(是常量),在Python中稱這類object是 immutable的,但是,如果變數指向的object是mutable的,那麼,Python的這種share object name的行為就要當心了,比如:
>>> L1 = [2,3,4]
>>> L2 = L1
如果此時,這樣做:
>>> L1 = 24
沒問題,因為L1重新指向一個object了,L2還是一個2, 3, 4的List,但是,如果這樣:
>>> L1[0] = 24
>>> L2
[24, 3, 4]
看到了嗎?L2也發生變化了,這是因為List本身是mutable的,是可以被修改的,由於L1和L2指向同一個object,所以,L1修改了object,從L2中讀出來的object也變化了。
17、我們會在後面的章節中講到如何關閉Python的這種變數共用object的特性,從而來避免上述的問題,也就是說,就算object一 樣,Python 也會為每個變數都分配這樣的object,這些變數都指向不同的object,這樣上述問題就完全避免了,但是浪費記憶體了。
18、Garbage collection。一開始我就說了,這個Python簡直和JAVA一模一樣!看看吧,這個garbage collection也和java一樣,反正就是哪個object沒有人reference了,就會被PVM釋放唄,比如:
>>> x = 42
>>> x = 'shrubbery' # Reclaim 42 now (?)
>>> x = 3.1415 # Reclaim 'shrubbery' now (?)
>>> x = [1,2,3] # Reclaim 3.1415 now (?)