Python學習筆記 - 作用域

MADAO是不會開花的發表於2019-01-03

Python有區域性作用域和全域性作用域。還可以細分為這四種情況:

  • L(local),區域性作用域
  • E(enclosing),巢狀作用域
  • G(global),全域性作用域
  • B(built-in),內建作用域

一. L(local),區域性作用域

如果一個變數在函式內部,那麼這個變數就叫做區域性變數,函式之外是無法訪問的,例子:

def say_name():
    name = 'Allen'
    print(name)


say_name()
print(name)
複製程式碼

Python學習筆記 - 作用域

函式在執行完畢後,會將它內部的變數回收(刪除)

如果想要在函式外部使用函式內部的變數。可以使用golbal關鍵字

def say_name():
    global name
    name = 'Allen'
    print(name)


say_name()
print(name)
複製程式碼

Python學習筆記 - 作用域

二. E(enclosing),巢狀作用域

作用域之間是可以相互巢狀的,比如兩個函式之間巢狀。裡面的函式可以訪問它外部函式作用域中的變數,但是外面的函式無法訪問內部函式的作用域,例子:

def foo():
    a = 1
    def bar():
        b = 2
        print(a)
    bar()
    print(b)

foo()
複製程式碼

Python學習筆記 - 作用域

但是,如果在內部函式中直接重新賦值外部函式作用域中的變數,外部函式作用域中的變數是不會改變的,會得到一個新的區域性變數。同樣的在函式中改變全域性作用域的變數,也是這樣。

b = 1
def foo():
    a = 1

    def bar():
        a = 2
        print('bar:', a)
    def fn():
        b = 2
        print('fn', b)
    bar()
    fn()
    print('foo:', a)

foo()
print('golbal:', b)
複製程式碼

Python學習筆記 - 作用域

如果想要修改原值,那麼就要用到nonlocal關鍵字,例子:

Python學習筆記 - 作用域

注意,nonlocal關鍵字只針對區域性變數,如果尋找的變數處於全域性作用域中,會報錯,,例子:

a = 1

def foo():
    nonlocal a
    a = 2
    print('foo:', a)

foo()

複製程式碼

Python學習筆記 - 作用域

如果nonloacl關鍵字在上一層中找到了變數,那麼就會停止尋找,如果沒有就繼續向上直到全域性作用域:

def foo():
    a = 1
    def bar():
        print('bar:', a)
        def fn():
            nonlocal a
            a = 2
            print('fn:', a)
        fn()
    bar()
    print('foo:', a)

foo()
複製程式碼

Python學習筆記 - 作用域

三. G(global),全域性作用域

全域性作用域就是模組最頂層宣告的變數。每一個.py結尾的檔案就是一個模組,每個模組都有不同的全域性作用域,當一個模組匯入另一個模組後,在當前模組就可以訪問另一個模組的全域性作用域中的變數了。全域性作用域中的變數,在當前模組的任何地方都可以訪問到。

# b.py

module_name = 'b'

# a.py

import b

print(b.module_name)
複製程式碼

Python學習筆記 - 作用域

四. B(built-in),內建作用域

內建作用域就是Python中內建模組中的變數,比如我們可以直接使用print方法而不用匯入任何模組。

Python學習筆記 - 作用域

Python中尋找變數的規則會按照LEGB規則尋找:

Local -> Enclosing -> Global -> Built-in

最後說一點的是,Python中沒有塊級作用域,也就是在類似for語句中定義的變數就是全域性作用域中的變數:

Python學習筆記 - 作用域

相關文章