Python回顧與整理1:Python基礎

weixin_33858249發表於2017-11-26

        學習Python其實也有好一段時間了,之前也做了不少筆記,但是要真正把Python學得很紮實,沒有對Python系統的瞭解是遠遠不夠的,哪怕是最基礎的知識點,所以決定好好地回顧整理。

        當然,就以《Python核心程式設計》這本書為綱,希望可以把自己對Python的理解連成系統的一條線。




1.語句和語法


  • `#`:註釋

  • `\`:換行,如果是閉合操作符如`( )`,`[ ]`,`{ }`等,可以不使用`\`

  • `:`:分號將程式碼頭和程式碼體分開

  • `縮排`:用以區分不同的程式碼塊

  • `;`:同一行寫多個語句,但不建議

  • `模組`:一個.py指令碼檔案就是一個模組




2.變數賦值


(1)賦值操作符:=

  • 在Python中,物件是通過引用傳遞的,賦值時,是將該物件的引用(不是一個值)賦給這個變數。

  • 另外,Python賦值語句沒有返回值,但可以使用賦值鏈:

1
2
3
4
5
6
>>> a  =  (a = 3)
  File "<stdin>", line 1
    = (a=3)
          ^
SyntaxError: invalid syntax
>>> y = = 3


(2)增量賦值

  • 只有類似+=這樣的增量賦值,沒有自增自減的方法

  • 特性:可變物件(列表,字典等)就修改(無需拷貝引用),不可變物件(數字,元組等)則分配一個新物件


(3)多重賦值

  • 一個物件可被多個變數引用,多個物件也可被多個物件引用

1
>>> x = = =1


(4)多元賦值:元組賦值

1
>>> (x, y, z) = (12'a string')
  • 不加括號也可以,但建議加上

  • 可用於兩值的交換

1
2
3
4
5
6
>>> x = 3; y = 4
>>> print x, y
3 4
>>> x, y = y, x
>>> print x, y
4 3




3.識別符號


  • 關鍵字識別符號:保留字,不能用於其他用途,否則會引起SyntaxError異常

  • 內建(built-in)識別符號:是__builtins__模組的成員,在程式開始或互動直譯器開始時,由Python直譯器自動匯入,可以將其作為Python全域性變數,可以重新賦值,但不建議

1
2
3
4
>>> dir
<built-in function dir>
>>> dir()
['__builtins__''__doc__''__name__''__package__']
  • __專用下劃線識別符號:

    __xxx:類中的私有變數名,不能用`from module import *`匯入,變數是私有時,建議使用這種方法

    __xxx__:系統定義名字,如內建識別符號


    另外,Pythonn不支援識別符號過載,所以任何時刻都只有一個名字繫結。




4.基本風格指南


  • 註釋:#號

  • 文件:模組,類宣告或函式宣告中第一個沒有賦值的字串,可通過obj.__doc__訪問

  • 縮排:以空格代替製表符

  • 識別符號名稱:名字簡短有意義

  • Python風格指南:import this



(1)模組結構和佈局

  • 起始行(Unix)

1
#/usr/bin/env python

        這樣僅輸入指令碼名字就可以執行指令碼,無需直接呼叫直譯器。

  • 模組文件

1
''this is a test module''

        可通過obj.__doc__訪問

  • 模組匯入

  • 變數定義:儘量使用區域性變數代替全域性變數

  • 類定義

  • 函式定義

  • 主程式

1
2
3
4
if __name__ == '__main__':
    My_function()
#如果模組是被匯入,__name__的值為模組名字;
#如果模組是被直接執行,__name__的值為'__main__';

        關於主程式,注意下面幾點:

  • 1.絕大部分模組建立的目的是被其它模組匯入而不是作為指令碼執行,總之只有一個模組,也就是包含主程式的模組會被執行;

  • 2.最高階別的Python語句(沒有縮排)在模組被匯入時就會被執行;

  • 3.通常只有主程式模組中有大量的頂級可執行程式碼,所有其他被匯入模組只應該有很少的頂級執行程式碼,所有的功能程式碼都應該封裝在函式或類當中。

    對於上面三點,只要聯絡自己在實際專案開發中的例子就可以很好的理解了。


(2)在主程式中書寫測試程式碼

    如果想測試被匯入的模組的某個函式的功能,就可以使用主程式的方法,引入並執行該函式,這就是測試功能的使用,當然在大型程式中,更傾向使用unittest。




5.記憶體管理


  • 變數定義:變數無須事先宣告

    在Python中無需顯式變數宣告語句,變數在第一次賦值時自動宣告。

  • 動態型別:變數無須指定型別

    Python中物件的型別和記憶體佔用都是執行時確定的。

  • 記憶體分配:不用關心記憶體管理

    Python直譯器承擔了內在管理的複雜任務。

  • 引用計數:物件回收

(1)增加引用計數

  • 當物件被建立並(將其引用)賦值給變數時,該物件的引用計數就被設定為1

  • 當一個物件(的引用)又被賦值給其他變數時,或作為引數傳遞給函式,方法或類例項時,或者被賦值為一個視窗物件(列表,字典等)的成員時,該物件新的一個引用會被建立,引用計數加1

1
2
3
4
>>> x = 3.14    #加1,下面每一步同理
>>> y = x
>>> foobar(x)
>>> myList = [123, x, 'xyz']

(2)減少引用計數

  • 一個本地引用離開其作用範圍

    如函式執行完畢後區域性變數被銷燬。

  • 物件別名被顯式銷燬

1
>>> del y
  • 當變數被賦值給另外一個物件時,原物件的引用計數也會自動減1

1
2
3
>>> foo = 'xyz'
>>> bar = foo
>>> foo = 123
  • 物件被從一個視窗物件中移除

1
myList.remove(x)
  • 視窗物件本身被銷燬

1
del myList

        即執行del y會產生下面兩個結果:

  • 1.從現在名稱空間中刪除y

  • 2.y變數對應的物件的引用計數減1

    需要注意的是,如果記憶體中仍然有在使用該物件,這會增加一個額外的引用,則它還不會被回收。


  • 垃圾收集

        直譯器跟蹤物件的引用計數,垃圾收集器負責釋放記憶體。其實際,垃圾收集器是一塊獨立程式碼,用來查詢引用計數為0的物件和那些引用計數雖然大於0但也應該被銷燬的物件(如迴圈引用的物件)。

        垃圾收集器 = 引用計數器 + 迴圈垃圾計數器,這在存在迴圈引用的情況中非常有用:

  • 迴圈引用:發生在至少兩個物件互相引用時,也就是當其它所有對它們的引用都消失時,他們兩者所產生的對各自的引用仍然存在,例如兩個類中有各自的一個例項

  • 引用計數器作用:當一個物件的引用計數變為0,直譯器會暫停,釋放掉這個物件和僅有這個物件可訪問(可到達的)其它物件(這樣的話,其它物件的引用計數必然是1)

  • 迴圈垃圾計數器作用:作為引用計數器的補充,垃圾收集器也會留心被分配的總量很大的(及未通過引用計數銷燬的那些)物件,在這種情況下,直譯器也會停下來,試圖清理所有未引用的迴圈

        基本可以理解,但具體怎麼實現的,就需要看Python的原始碼分析了。




6.第一個Python程式


    主要提及一點:使用區域性變數替換模組變數

    例如,你要使用os.linesep,如果你多次使用,那麼建議將其定義為一個本模組的全域性變數或區域性變數,這將會加快查詢的速度,因為對於os.linesep,要進行下面兩步:

  • 首先要查詢os,確認其是一個模組

  • 在這個模組中查詢linesep變數

    將經常用到的模組屬性替換為一個本地引用,可以讓程式跑得更快。




本文轉自 xpleaf 51CTO部落格,原文連結:http://blog.51cto.com/xpleaf/1750127,如需轉載請自行聯絡原作者

相關文章