python中變數的查找機制: 局部作用域--外部函數作用域--全局作用域--內建函數作用域 其實一般內建函數中的作用域很少會涉及到,因為內建函數其實是一個封裝好的實例函數, 它的內部變數一般在函數外部無法獲取到 ...
首先必須要提一下python程式執行過程中變數的查找規則
較官方的查找機制是:
局部作用域--外部函數作用域--全局作用域--內建函數作用域
其實一般內建函數中的作用域很少會涉及到,因為內建函數其實是一個封裝好的實例函數,
它的內部變數一般在函數外部無法獲取到
什麼是局部作用域,外部函數作用域和全局作用域?
1. 局部作用域
指的是函數內部的作用域
例如:
def fn(a,b,c):
d=1
process
函數內的變數d位處的作用域就是函數的內部作用域,另外給fn()傳入的參數a,b,c也位於函數內部的作用域內,
函數一旦調用完畢就會在記憶體中銷毀
2. 外部函數函數作用域
例如:
def fn1():
e=1
def fn2():
pass
變數e所在的區域,外有fn1包裹,下有fn2函數,變數e所在的作用域就為外部函數作用域,外部函數作用域可以有
多個,這取決於函數有多少層嵌套
3. 全局作用域
例如:
f=1
def fn1():
e=1
def fn2():
pass
(此例在2.中例子基礎上增加了變數f)
可見,變數f所在的作用域就是全局作用域,就是沒有被函數包裹(即在所有函數之外)的作用域
為什麼要區分局部變數和全局變數:
1. 避免變數名的衝突,因為python是一種類型較弱的語言,變數可以隨時被賦值和修改為各種類型的數據,
這樣容易引起命名上的衝突,局部變數和全局變數的區分使得這種衝突得到緩解
2. 為了提高效率,減少記憶體的占有,python規定局部變數在函數調用完之後就刪除,而全局變數則不會刪除
在談及變數的命名空間這個話題必須要知道的兩個語句:
global語句和nonlocal語句
global語句
一般條件下,全局作用域內定義的變數在局部變數內是無法修改的,而global語句則例外,
它在函數內部聲明一個變數是全局內的變數,需要調用時去全局尋找,因此可以改變全局變數
註意:
要在函數內部聲明這個變數,則在全局作用域中要事先定義(賦值)這個變數,同時在這個函數
的局部作用域內不能存在相同變數名的變數,否則程式會出錯
nonlocal語句
這個語句跟global語句的功能有些類似,區別在於它是在在局部作用域內改變外部函數作用域的變數
那麼在實際應用中這兩個語句到底有什麼用呢?
舉兩個簡單的例子
1.
L=[] #全局變數--一個列表
while True: #此處暫且定義一個死迴圈,可以根據實際修改迴圈條件
def fn1():
global L #在函數內部給列表添加數據
L.append('abc') #abc只是一個例子,每次調用fn1()都可以增添不同數據
在迴圈內每次調用fn1函數都可以往列表中增添‘abc’字元串,如果L列表定義在函數內部,
則每次調用函數都會初始化列表L,就沒有意義了。所以global就有這麼一個作用--實現
全局變數在函數內部的修改。
2.
a=0
def fn2():
global a
a+=1
process
fn2()
fn2()
這個例子反映global語句的作用是記錄函數fn2函數被調用的次數,每次調用fn2函數,a都會自增1
在函數外部可以根據變數a的值知道fn2函數被調用了多少次
nonlocal語句的用法和global語句的用法差不多,讀者可以依樣畫葫蘆,敲敲代碼就知道怎麼用了,
我在這裡就不贅述了