函數基礎-09名稱空間和做用域

函數內部的函數只能在函數內部調用,不能在函數外部調用?!
緣由: 名稱空間問題!!!python

一丶名稱空間

名稱空間(name spaces):在內存管理那一章節時,咱們曾說到變量的建立其實就是在內存中開闢了一個新的空間。可是咱們一直在迴避變量名的存儲,其實在內存中有一塊內存存儲變量名與變量間的綁定關係的空間,而這個空間稱爲名稱空間。app

1.1 內置名稱空間

內置名稱空間:存放Pyhton解釋器自帶的名字,如int、float、len函數

生命週期:在解釋器啓動時生效,在解釋器關閉時失效spa

1.2 全局名稱空間

全局名稱空間:除了內置和局部的名字以外,其他都存放在全局名稱空間,以下面代碼中的
x、func、l、z
生命週期:在文件執行時生效,在文件執行結束後失效code

x = 1

def func():
    pass

l = [1, 2]

if 3 > 2:
    if 4 > 3:
        z = 3

1.3 局部名稱空間

局部名稱空間:用於存放函數調用期間函數體產生的名字,以下面代碼的f2對象

生命週期:在文件執行時函數調用期間時生效,在函數執行結束後失效生命週期

def f1():
    def f2():
        print('from f2')
    f2()

f1()

1.4 加載順序

因爲.py文件是由Python解釋器打開的,所以必定是在Python解釋器中的內置名稱空間加載結束後,文件纔開始打開,這個時候纔會產生全局名稱空間,但文件內有某一個函數被調用的時候,纔會開始產生局部名稱空間,所以名稱空間的加載順序爲:內置--》全局--》局部。內存

1.5 查找順序

因爲名稱空間是用來存放變量名與值之間的綁定關係的,因此但凡要查找名字,必定是從三者之一找到,查找順序爲:
從當前的所在位置開始查找,若是當前所在的位置爲局部名稱空間,則查找順序爲:局部--》全局--》內置。作用域

x = 1
y = 2
len = 100

def func():
    y = 3
    len = 1000
    print(f"y: {y}")
    print(f"len: {len}")
    # print(a)  # NameError: name 'a' is not defined

func()

y: 3 len: 1000內存管理

x = 1

def func():
    print(x)

x = 10
func()

二丶做用域

域指的是區域,做用域即做用的區域。

2.1 全局做用域

全局做用域:全局有效,全局存活,包含內置名稱空間和全局名稱空間。

# 全局做用域
x = 1

def bar():
    print(x)

bar()

1

2.2 局部做用域

局部做用域:局部有小,臨時存儲,只包含局部名稱空間。

# 局部做用域
def f1():
    def f2():
        def f3():
            print(x)
        x = 2
        f3()
    f2()

f1()

2

2.3 注意點

須要注意的是:做用域關係在函數定義階段就固定死了,與函數的調用無關。

# 做用域注意點
x = 1

def f1():  # 定義階段x=1
    print(x)

def f2():
    x = 2
    f1()

f2()

1

2.4 函數對象+做用域應用

# 做用域應用
def f1():
    def inner():
        print('from inner')
    return inner

f = f1()  # 把局部定義的函數放在全局之中

def bar():
    f()

bar()

from inner


三丶補充知識點

3.1 global關鍵字

修改全局做用域中的變量.

x = 1

def f1():
    x = 2

    def f2():
        #         global x  # 修改全局
        x = 3
    f2()

f1()
print(x)

1

x = 1

def f1():
    x = 2
    def f2():
        global x  # 修改全局
        x = 3
    f2()

f1()
print(x)

3

3.2 nonlocal關鍵字

修改局部做用域中的變量。

x = 1

def f1():
    x = 2
    def f2():
        #         nonlocal x
        x = 3

    f2()
    print(x)

f1()

2

x = 1

def f1():
    x = 2
    def f2():
        nonlocal x
        x = 3

    f2()
    print(x)

f1()

3

3.3 注意點

 1.在局部想要修改全局的可變類型,不須要任何聲明,能夠直接修改。
 2.在局部若是想要修改全局的不可變類型,須要藉助global聲明,聲明爲全局的變量,便可直接修改。

lis = []

def f1():
    lis.append(1)

print(f"調用函數前: {lis}")
f1()
print(f"調用函數後: {lis}")

調用函數前: [] 調用函數後: [1]

相關文章
相關標籤/搜索