1. 程式人生 > >函式與模組間作用域的區別

函式與模組間作用域的區別

在開始編寫函式之前,我們編寫的所有的程式碼多少位於一個模組的頂層(也就是說,並不是巢狀在def之中),所以我們使用的變數名要麼就是存在於模組檔案本身,要麼就是Python內建預先定義好的(例如open).函式提供了巢狀的名稱空間(作用域),使其內部使用的變數名本地化,以便函式內部使用的變數名不會與函式外(在一個模組或是其他的函式中)的變數名產生衝突.

再次宣告,函式定義了本地作用域而模組定義的是全域性作用域,這兩個作用域有如下的關係:

  • 內嵌的模組是全域性作用域.每一個模組多少一個全域性作用域(也就是說,一個創建於模組檔案頂層的變數的名稱空間).對於外部的全域性變數就成為一個模組物件的屬性,但是在一個模組中能夠像簡單的變數一樣使用.
  • 全域性作用域的作用範圍僅限於單個檔案. 別被這裡的'全域性'所迷惑,這裡的全域性指的是在一個檔案的頂層的變數名僅對於這個檔案內部的程式碼而言是全域性的.在python中是沒有基於一個單個的,無所不包的情景檔案的全域性作用域的.替代這種的方法是,變數名由模組檔案隔開,並且必須精確地匯入一個模組檔案才能夠使用這個檔案中定義的變數名.當你在Python中聽到'全域性的',你就應該想到'模組'.
  • 每次對函式的呼叫都建立了一個新的本地作用域. 也就是說,將會存在由那個函式建立的變數的名稱空間.可以認為每一個def語句(以及lambda表示式)都定義了一個新的本地作用域,但是Python允許函式在迴圈中呼叫自身(遞迴),所以從技術上講,本地作用域實際上對應的是函式的呼叫.換句話說,每一個函式呼叫都建立了一個新的本地名稱空間.遞迴在處理不能提前預知的流程結構時是一個有用工具.
  • 賦值的變數名除非宣告為全域性變數或非本地變數,否則均為本地變數. 在預設情況下,所有函式定義內部的變數名是位於本地作用域內的(與函式呼叫相關的).如果需要給一個在函式內部卻位於模組檔案頂層的變數名賦值,需要在函式內部通過global語句宣告.如果需要給位於一個巢狀的def中的名稱賦值,從Python3.0開始可以通過在一條nonloal語句中宣告它來做到.
  • 所有其他的變數名都可以歸納為本地,全域性或者內建的. 在函式定義內部的尚未賦值的變數名是一個在一定範圍內(在這個def內部)的本地變數,全域性(在一個模組的名稱空間內部)或者內建變數(由Python的預定義__builtin__模組提供的).