python基本語法和程式設計風格
這篇部落格簡單記錄一下python的基本語法和程式設計風格, 以及變數所佔的記憶體是何如分配和回收的。
1 語法和語句
1.1 註釋
‘#’符號在python裡面代表註釋符,python編譯器會自動忽略註釋符後面的語句,值得注意的是,#可以在一行的任何地方開始,而不用擔心python語句的縮排問題。
1.2 繼續 \
python語句,使用\來將一行程式碼分解為多行,比如:
>>> print "i love this \
... world"
執行結果為:
i love this world
如果第二行縮排的話,如:
>>> print "i love this \
... world"
則執行結果就會變成
i love this world
也就是說,縮排的部分被解釋為空格了。
1.3 同一行輸入多個語句 ;
用;可以讓多行程式碼寫在同一行上,如
a = 1; print a
但是建議不要這麼寫,會降低程式碼可讀性。
2變數賦值
在python中,變數賦值不是直接把值賦給變數,而是把該物件的引用賦值給變數。
多元賦值:
>>> x, y = 22, 33
>>> x
22
>>> y
33
因此,我們可以利用python的多元賦值,不用中間變數就可以把兩個變數的值進行交換
>>> x, y = y, x
3 識別符號
3.1 關鍵字
關鍵字列表和 iskeyword()函式都放入了 keyword模組以便查閱。
3.2 專用下劃線識別符號
_XXX 不用’from module import *’匯入
XXX 系統定義名字
__XXX 類中的私有變數名
因此,儘量避免用下劃線開頭定義變數名字,當變數是私有的時候,可以使用下劃線開頭定義變數。
4 基本風格指南
4.1 縮排
儘量使用4個空格來縮排,製表符在不同的文字編輯器對它的解釋是不用的,所以推薦不要使用製表符。
Guido van Rossum 在多年前寫下 Python 程式碼風格指南。目前它已經被至少三個 PEP 代替:7(C 程式碼風格指南)、8(Python 程式碼風格指南)和 257(文件字串規範)。這些 PEP 被歸檔、維護並定期更新。
4.2 模組結構和佈局
python檔案模組應該使用一種統一的佈局方式,便於閱讀,比如這種:
(1) 起始行(Unix)
(2) 模組文件
(3) 模組匯入
(4) 變數定義
(5) 類定義
(6) 函式定義
(7) 主程式
這個順序,直接上圖就能比較清楚的解釋了:
通常,python所有語句都有能力執行程式碼,而不是像其它的程式語言,只有main函式才可以。所以一個比較安全的做法,就是把所有可以執行的函式都寫在main函式裡,而main函式外,儘量不寫能夠執行的程式碼。
由於主程式程式碼無論模組是被匯入還是被直接執行都會執行, 我們必須知道模組如何決定執行方向。一個應用程式可能需要匯入另一個應用程式的一個模組,以便重用一些有用的程式碼(否則就只能用拷貝貼上那種非面向物件的愚蠢手段)。這種情況下,你只想訪問那些位於其
它應用程式中的程式碼,而不是想執行那個應用程式。因此一個問題出現了,“Python 是否有一種方法能在執行時檢測該模組是被匯入還是被直接執行呢?” 答案就是……(鼓聲雷動)…..沒錯! name 系統變數就是正確答案。
如果模組是被匯入, name 的值為模組名字
如果模組是被直接執行, name 的值為 ‘main’
5 記憶體管理
5.1 引用計數
要保持追蹤記憶體中的物件,python使用了引用計數這一簡單的技術,也就是說,每個物件都有一個引用計數器,用來記錄每個物件有多少引用,當物件的引用計數器為0時,該物件就會被銷燬。和別的語言不用,python在賦值的時候,是把引用賦值給物件,而不是值本身。比如說, x = 1, python會建立1這個物件,然後把1這個物件的引用賦值給x,當執行 y = 1 時,會再把 1這個物件的引用賦值給y,這個時候,1的引用計數器就變成2了。如果我們不執行 y =1,而是 y = x,會發生同樣的事情。
總之,物件的引用計數在:
物件被建立
x = 3.14
或另外的別名被建立
y = x
或被作為引數傳遞給函式(新的本地引用)
foobar(x)
或成為容器物件的一個元素
myList = [123, x, ‘xyz’]
del語句:
既然引用計數可以增加,那麼也肯定可以減少,比如使用del語句。由於 x, y 都指向 1,del x 之後,1的引用計數就會減1,因為只有y指向1了。
另外還有很多情況,1的引用計數會減少,比如:
一個本地引用離開了其作用範圍。比如 foobar()(參見上一下例子)函式結束時。
物件的別名被顯式的銷燬。
del y
物件的一個別名被賦值給其它的物件
x = 123
物件被從一個視窗物件中移除
myList.remove(x)
視窗物件本身被銷燬
del myList
5.2 垃圾收集
不再被使用的記憶體會被垃圾收集的機制銷燬,也就是說,引用計數為0的物件會被銷燬,但實際情況也不一定都是這樣,比如下面的例子:
>>> a = [1]
>>> b = [2]
>>> a.append(b)
>>> b.append(a)
>>> a
[1, [2, [...]]]
>>> b
[2, [1, [...]]]
在這個例子裡,a在引用b,b又在引用a,雙方都在引用對方,所以它們兩個永遠不可能引用計數為0。因此,如果只按照引用計數來銷燬變數的畫,a和b永遠都不會被銷燬。這個時候,python的迴圈垃圾收集器就派上用場了。因此,python的垃圾收集實際上就是一個引用計數器和一個迴圈垃圾收集器。
參考資料:Python核心程式設計(中文第二版)