03 Python 基礎 - 《Python 核心編程》

來源:互聯網
上載者:User

標籤:

?? 語句和文法?? 變數賦值?? 標識符和關鍵字?? 基本風格指南?? 記憶體管理?? 第一個 Python 程式3.1語句和文法Python 語句中有一些基本規則和特殊字元:
    ?? 井號(#)表示之後的字元為 Python 注釋
    ?? 換行 (\n) 是標準的行分隔字元(通常一個語句一行)
    ?? 反斜線 ( \ ) 繼續上一行
    ?? 分號 ( ; )將兩個語句串連在一行中
    ?? 冒號 ( : ) 將代碼塊的頭和體分開
    ?? 語句(代碼塊)用縮排塊的方式體現 (縮排四個空格寬度,避免使用定位字元)
    ?? 不同的縮排深度分隔不同的代碼塊
    ?? Python 檔案以模組的形式組織 (當一個模組變得過大,並且驅動了太多功能的話,就應該考慮拆一些代碼出來另外建一個模組.)注釋( # )    和很多 Unix 指令碼類似,Python 備註陳述式從 # 字元開始,注釋可以在一行 的任何地方開始,解譯器會忽略掉該行 # 之後的所有內容。要正確的使用注釋。繼續( \ )    Python 語句,一般使用換行分隔,也就是說一行一個語句。一行過長的語句可以使用反斜 杠( \ ) 分解成幾行,如下例:        # check conditions        if (weather_is_hot == 1) and \        (shark_warnings == 0):            send_goto_beach_mesg_to_pager()    有兩種例外情況一個語句不使用反斜線也可以跨行。        在使用閉合操作符時,單一語句可以 跨多行,例如:在含有小括弧、中括弧、花括弧時可以多行書寫。        另外就是三引號包括下的字串也可以跨行書寫。    如果要在使用反斜線換行和使用括弧元素換行作一個選擇,我們推薦使用括弧,這樣可讀 性會更好。多個語句構成程式碼群組(:):    縮排相同的一組語句構成一個代碼塊,我們稱之程式碼群組。    像if、while、def 和class 這樣 的複合陳述式,首行以關鍵字開始,以冒號( : )結束,該行之後的一行或多行代碼構成程式碼群組。我們將首行及後面的程式碼群組稱為一個子句(clause)。程式碼群組由不同的縮排分隔    代碼的層次關係是通過同樣 深度的空格或定位字元縮排體現的。    核心風格:縮排四個空格寬度,避免使用定位字元         對一個初次使用空白字元作為代碼塊分界的人來說,遇到的第一個問題是:縮排多大寬度 才合適?兩個太少,六到八個又太多,因此我們推薦使用四個空格寬度。        需要說明一點,不同的文字編輯器中定位字元代表的空白寬度不一,如果你的代碼要跨平台應用,或者會被不同的編輯器讀寫,建議你不要使用定位字元。        使用空格或定位字元這兩種風格都得到了Python 創始人Guido  van Rossum 的支援,並被收錄到Python 代碼風格指南文檔。同一行書寫多個語句(;)    分號( ; )允許你將多個語句寫在同一行上,語句之間用分號隔開,而這些語句也不能在這 行開始一個新的代碼塊。    必須指出一點, 同一行上書寫多個語句會大大降低代碼的可讀性,Python 雖然允許但不 提倡你這麼做。模組    每一個Python 指令檔都可以被當成是一個模組。模組以磁碟檔案的形式存在。當一個模 塊變得過大,並且驅動了太多功能的話,就應該考慮拆一些代碼出來另外建一個模組。    模組裡的代碼可以是一段直接執行的指令碼,也可以是一堆類似庫函數的代碼,從而可以被別的模組匯入(import)調用。    模組可以包含直接啟動並執行代碼塊、類定義、函數定義或這幾者的組合。

3.2 變數賦值

賦值運算子    Python 語言中, 等號(=)是主要的賦值運算子。    注意,賦值並不是直接將一個值賦給一個變數, 儘管你可能根據其它語言編程經驗認為應該如此。在Python 語言中,對象是通過引用傳遞的。在賦值時,不管這個對象是新建立的,還是一個已經存在的,都是將該對象的引用(並不是值)賦值給變數。同樣的, 如果你比較熟悉C, 你會知道指派陳述式其實是被當成一個運算式(可以傳回值)。不過這條並不適合於 Python, Python 的指派陳述式不會傳回值。鏈式賦值
>>> y = x = x + 1>>> x, y(2, 2)
增量賦值
>>> x = 1>>> x += 1>>> x2

多元賦值 (採用這種方式賦值時, 等號兩邊的對象都是元組)

>>> x, y, z = 1, 2, ‘a string‘>>> x1>>> y2>>> z‘a string‘Python 的多元賦值方式可以實現無需中間變數交換兩個變數的值。

3.3 標識符

合法的Python 標識符    Python 標識符字串規則和其他大部分用C 編寫的進階語言相似:        ?? 第一個字元必須是字母或底線(_)
        ?? 剩下的字元可以是字母和數字或底線
        ?? 大小寫敏感關鍵字

內建

    除了關鍵字之外,Python 還有可以在任何一級代碼使用的“內建”的名字集合,這些名字 可以由解譯器設定或使用。    雖然built-in 不是關鍵字,但是應該把它當作“系統保留字”,不做他用。        然而,有些情況要求覆蓋(也就是:重定義,替換)它們。    Python 不支援重載標識符,所以任何時刻都只有一個名字綁定。     我們還可以告訴進階讀者built-in 是__builtins__模組的成員,在你的程式開始或在互動 解譯器中給出>>>提示之前,由解譯器自動匯入的。    把它們看成適用在任何一級Python 代碼的全域變數。專用底線標識符    Python 用底線作為變數首碼和尾碼指定特殊變數。
總結:?? _xxx 不用‘from module import *‘匯入?? __xxx__系統定義名字
?? __xxx 類中的私人變數名
    核心風格:避免用底線作為變數名的開始        因為底線對解譯器有特殊的意義,而且是內建標識符所使用的符號,我們建議程式員避免用底線作為變數名的開始。        一般來講,變數名_xxx 被看作是“私人的”,在模組或類外不可以使用。        當變數是私人的時候,用_xxx 來表示變數是很好的習慣。因為變數名__xxx__對Python 來說有特殊含義,對於普通的變數應當避免這種命名風格。3.4 基本風格指南    注釋,文檔,縮排,標識符    模組結構和布局        # (1) 起始行(Unix)        # (2) 模組文檔        # (3) 模組匯入        # (4) 變數定義        # (5) 類定義        # (6) 函數定義        # (7) 主程式        (1) 起始行            通常只有在類Unix 環境下才使用起始行,有起始行就能夠僅輸入指令碼名字來執行指令碼,無        需直接調用解譯器。        (2)模組文檔            簡要介紹模組的功能及重要全域變數的含義,模組外可通過 module.__doc__ 訪問這些內 容。         (3)模組匯入            匯入當前模組的代碼需要的所有模組;每個模組僅匯入一次(當前模組被載入時);函數內部的模組匯入代碼不會被執行, 除非該函數正在執行。         (4)變數定義            這裡定義的變數為全域變數,本模組中的所有函數都可直接使用。            從好的編程風格角度說, 除非必須,否則就要盡量使用局部變數代替全域變數,如果堅持這樣做,你的代碼就不但容易維護,而且還可以提高效能並節省記憶體。         (5)類定義語句            所有的類都需要在這裡定義。當模組被匯入時class 語句會被執行, 類也就會被定義。類的文檔變數是class.__doc__。         (6)函數定義語句            此處定義的函數可以通過module.function()在外部被訪問到,當模組被匯入時 def 語句會被執行,函數也就都會定義好,函數的文檔變數是function.__doc__。         (7) 主程式            無論這個模組是被別的模組匯入還是作為指令碼直接執行,都會執行這部分代碼。通常這裡 不會有太多功能性代碼,而是根據執行的模式調用不同的函數。                          Figure 3–1 Typical Python file structure    推薦代碼風格:主程式調用main()函數 
        主程式碼通常都和你前面看到的代碼相似,檢查 __name__ 變數的值然後再執行相應的 調用(參閱下一頁的核心筆記)。
        主程式中的代碼通常包括變數賦值, 類定義和函數定義,隨後檢查__name__來決定是否調用另一個函數(通常調用main()函數)來完成該模組的功能。            主程式通常都是做這些事。(我們上面的例子中使用test()而不是main()是為了避免你在讀到核心筆記前感到迷惑。) 
        不管用什麼名字,我們想強調一點那就是:這兒是放置測試代碼的好地方。大部分的Python 模組都是用於匯入調用的,直接運行模組應該調用該模組的迴歸測試代碼。        請記住,絕大部分的模組建立 的目的是為了被別人調用而不是作為獨立執行的指令碼。        只有一個模組,也就是包含主程 序的模組會被直接執行,或由使用者通過命令列執行,或作為批處理執行, 或由Unix cron 任務定時執行,或通過Web 服務器調用,或通過GUI 執行。    核心筆記:__name__ 指示模組應如何被載入        如果模組是被匯入, __name__ 的值為模組名字         如果模組是被直接執行, __name__ 的值為 ‘__main__‘3.5 記憶體管理
?? 變數無須事先聲明
?? 變數無須指定類型
?? 程式員不用關心記憶體管理
?? 變數名會被“回收”
?? del 語句能夠直接釋放資源
變數定義
    在Python 中,無需顯式變數聲明語句,變數在第一次被賦值時自動聲明。
    和其他大多數語言一樣,變數只有被建立和賦值後才能被使用。
動態類型
    Python 中不但變數名無需事先聲明,而且也無需型別宣告。
    Python 語言中, 對象的類型和記憶體佔用都是運行時確定的。
    儘管代碼被編譯成位元組碼,Python 仍然是一種解釋型語言。
    在建立--也就是賦值時,解譯器會根據文法和右側的運算元來決定新對象的類型。
    在對象建立後,一個該對象的引用會被賦值給左側的變數。記憶體配置    作為一個負責任的程式員,我們知道在為變數分配記憶體時,是在借用系統資源,在用完之 後, 應該釋放借用的系統資源。    Python 解譯器承擔了記憶體管理的複雜任務, 這大大簡化了應用程式的編寫。    你只需要關心你要解決的問題,至於底層的事情放心交給Python 解譯器去做就行了。引用計數    每個對象各有多少個引用, 簡稱引用計數。

    一個引用計數內部跟蹤變數,稱為一個引用計數器。

    當這個對象不再需要時, 也就是說, 這個對象的引用計數變為0 時, 它被記憶體回收。增加引用計數    當對象被建立並(將其引用)賦值給變數時,該對象的引用計數就被設定為1。    當同一個對象(的引用)又被賦值給其它變數時,        或作為參數傳遞給函數, 方法或類執行個體 時,        或者被賦值為一個視窗對象的成員時,該對象的一個新的引用,或者稱作別名,就被建立(則該對象的引用計數自動加1)。對象的引用計數在     ?? 對象被建立        x = 3.14    ?? 或另外的別名被建立        y = x    ?? 或被作為參數傳遞給函數(新的本地引用)        foobar(x)    ?? 或成為容器物件的一個元素        myList = [123, x, ‘xyz‘]減少引用計數    當對象的引用被銷毀時,引用計數會減小。        最明顯的例子就是當引用離開其作用範圍時,這種情況最經常出現在函數運行結束時,所有局部變數都被自動銷毀,對象的引用計數也就隨之減少。    當變數被賦值給另外一個對象時,原對象的引用計數也會自動減1:        foo = ‘xyz‘   #‘xyz‘  1        bar = foo     #‘xyz‘  2        foo = 123    #‘xyz‘  1    其它造成對象的引用計數減少的方式包括使用 del 語句刪除一個變數(參閱下一節), 或 者當一個對象被移出一個視窗對象時(或該容器物件本身的引用計數變成了0 時)。    一個對象的引用計數在以下情況會減少:        ?? 一個本地引用離開了其作用範圍。比如 foobar()(參見上一下例子)函數結束時。        ?? 對象的別名被顯式的銷毀。            del y # or del x                ?? 從現在的名字空間中刪除 y                ?? x 的引用計數減一        ?? 對象的一個別名被賦值給其它的對象            x = 123        ?? 對象被從一個視窗對象中移除            myList.remove(x)        ?? 視窗對象本身被銷毀            del myList # or goes out-of-scope垃圾收集    不再被使用的記憶體會被一種稱為垃圾收集的機制釋放。    雖然解譯器跟蹤對象 的引用計數, 但垃圾收集器負責釋放記憶體。    垃圾收集器是一塊獨立代碼, 它用來尋找引用計數為0 的對象。        它也負責檢查那些雖然引用計數大於0 但也應該被銷毀的對象。         特定情形會導致循環參考。         一個循環參考發生在當你有至少兩個對象互相引用時, 也就是說所有的引用都消失時, 這 些引用仍然存在, 這說明只靠引用計數是不夠的。    Python 的垃圾收集器實際上是一個引用計數器和一個迴圈垃圾收集器。    當一個對象的引用計數變為0,解譯器會暫停,釋放掉這個對象和僅有這個對象可訪問(可到達)的其它對象。    作為引用計數的補充, 垃圾收集器也會留心被分配的總量很大(及未通過引用計數銷毀的那些)的對象。    在這種情況下, 解譯器會暫停下來, 試圖清理所有未引用的迴圈。核心技巧:使用局部變數替換模組變數
    類似 os.linesep 這樣的名字需要解譯器做兩次查詢:
        (1)尋找os 以確認它是一個模組,
        (2)在這個模組中尋找 linesep 變數。因為模組也是全域變數, 我們多消耗了系統資源。
    如果你在一個函數中類似這樣頻繁使用一個屬性,我們建議你為該屬性取一個本地變數別名。
    變數尋找速度將會快很多--在尋找全域變數之前, 總是先尋找本地變數。
    這也是一個讓你的程式跑的更快的技巧: 將經常用到的模組屬性替換為一個本地引用。代碼跑得更快,而也不用老是敲那麼長的變數名了。3.6 相關模組和開發工具    Python 代碼風格指南(PEP8), Python 快速參考和Python 常見問答都是開發人員很重要的“工具”。    另外, 還有一些模組會協助你成為一個優秀的Python 程式員。
?? Debugger: pdb
?? Logger: logging
?? Profilers: profile, hotshot, cProfile

03 Python 基礎 - 《Python 核心編程》

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.