1. 程式人生 > 其它 >名稱空間和作用域

名稱空間和作用域

作用域,就是 python 程式中,可以直接訪問名稱空間的正文區域。

python 中程式的變數也是有作用範圍的,在範圍之外是不能訪問的,能訪問的範圍決定於變數定義/賦值的位置。

區域性作用域(Local,最內層,函式或閉包函式內,包含區域性變數)

閉包函式外的作用域(Enclosing),主要就是巢狀函式中閉包函式外的區域,包含非區域性(non-local)也非全域性(non-global的變數)

全域性作用域(glocal),當前程式的最外層區域,包含本程式檔案/模組的全域性變數

內建作用域(built-in)包含了內建函式、關鍵字等。在使用一個變數的時候,會按照由內而外的順序取尋找該變數的定義,內層可遮蔽外層

num1=123   #全域性作用域變數
def fun():
    num1=234  # 閉包函式外的函式中變數
    def fun1():
        num1=345  #區域性作用域變數

python 中只有模組(module)、類(class)以及函式(def、lambda)能引入新的作用域

其他語句塊是不會引入新的作用域的,如 if…else… 、try…except…和 for/while等

def fun():
    inner=21
    
list1=[1,2,3,4]
a='abcdef'
for i in list1:
    a+=a[i]
print(i)  #這裡是可以使用i的,因為i在for中定義了,for不形成新作用域
print(a)

# print(inner)  #這裡會報錯,因為inner只在函式fun中定義了,在函式外沒定義,所以找不到inner變數

global 和 nonlocal 關鍵字

global 用在區域性作用域或閉包函式外的函式作用域中,用來指出在該作用域中使用的變數是全域性變數,而非區域性變數,該變數可以是在全域性作用域中出現過的變數,也可以是沒出現過的變數。
但是必須在第一次使用之前宣告,否則就會報錯

num = 0 # 這是一個全域性變數
def fun1():
    num =2
    # global num # 函式內,在global宣告之前已經使用過num.這裡會報錯
    print ("函式內: ", num)
    return num

fun1()
print ("函式外: ", num)

nonlocal 用在閉包函式內的函式作用域中

,用來指出在該作用域中使用的同名變數不是區域性變數,而是一個外部變數,注意,
若閉包函式外的函式中沒有此同名變數則會報錯

num = 0 # 這是一個全域性變數
def fun1():
    # global num
    num = 1 # num 在這裡是全域性變數.
    def fun2():
        nonlocal num # 這裡會報錯,因為在外層函式中沒有同名區域性變數;註釋掉global num就不會報錯了
        num=2
        print("閉包函式內: ", num)
        return num
    fun2()
    print ("函式內: ", num)
    return num

fun1()
print ("函式外: ", num)

緣由

不可變型別

總的來說對於不可變型別:像 int 、 float 、 str 等型別;
定義即賦值,修改實際上是新的定義,這一類變數的定義和修改都是使用賦值運算子 '='。

可變型別

像 list 、 set 、 dict 等型別是一類可變型別,所謂可變型別,就是定義之後,還可以對變數進行修改,修改前後,
該變數的 id 不變,這一類變數定義使用賦值運算子,
修改則需要下標(或鍵),還可以有插入、刪除等操作。

list1=['a','b','c']
def fun1():
    # global list1
    list1[0]='f'  #這裡已經使用過全域性變量了,在函式內就不能再定義同名的區域性變量了
    print('fun1內,打算定義一個與全域性變數同名的區域性變數:')
    """
    若這一行沒有註釋掉#global list1就不會報錯
    緣由是在同一個作用域中被定義了全域性變數,此時是全域性變數被賦值,修改
    """
    # list1=['s']  #這裡定義同名的變數,會報錯;   


def fun2():
    print('fun2內,打算定義一個與全域性變數同名的區域性變數:')
    list1=[123,'abc']   #這裡定義了一個與全域性變數同名的區域性變數
    list1.append('123') #這裡使用的也是區域性變數
    print('fun2函式內:',list1)
fun1()
print('執行fun1之後,函式外:',list1)
fun2()
print('執行fun2之後,函式外:',list1)

參考Python細節之7、global與nonlocal的使用
之前也寫過,但不詳細global與nonlocal

努力拼搏吧,不要害怕,不要去規劃,不要迷茫。但你一定要在路上一直的走下去,儘管可能停滯不前,但也要走。