25.函數(4)----名稱空間與作用域

一.名稱空間

1.認識名稱空間

我們都知道,變量在內存中存儲的方式如下:
在這裏插入圖片描述
所有的名稱(變量名、函數名等)都放在棧區,那麼就會存在一個問題,就是名稱重複,假設有一個名爲a的函數,同時也存在一個名爲a的變量,這樣的話肯定有一個失效,被另一個覆蓋。爲了解決這個問題,python將棧區空間劃分爲3部分,即內置名稱空間、全局名稱空間、局部名稱空間。如下圖:
在這裏插入圖片描述
所以名稱空間就是存放名字的地方的代稱,不是真是存在的東西,只是對棧區的一個劃分。

2.三種名稱空間詳解

1.內置名稱空間

內置名稱空間: 存放python解釋器自帶的名稱,比如print函數,我們自己又沒有定義,但是能直接用
存活週期: python解釋器啓動則產生,python解釋器關閉則銷燬
內置名稱空間只有一個

type(print)

結果如下:在這裏插入圖片描述

2.局部名稱空間
局部名稱空間: 存放函數體代碼中的名稱
存活週期: 函數調用時創建,函數執行完畢則銷燬
局部名稱空間可以有多個,不管是不是同一個函數,調用一次創建一個局部名稱空間。

3.全局名稱空間
全局名稱空間: 存放除內置和局部名稱空間外所有名稱
存活週期:python程序執行時創建,python程序執行完畢則銷燬
全局名稱空間只有一個

總結:

名稱空間 存放名稱 存貨週期 個數
內置名稱空間 python解釋器自帶的名稱 python解釋器啓動產生,python解釋器關閉銷燬 1個
全局名稱空間 除內置和局部名稱空間外其他所有名稱 python程序執行創建,python程序執行完畢銷燬 1個
局部名稱空間 函數體代碼中的名稱 函數調用創建,調用完畢銷燬 多個

3.名稱空間的加載順序

在這裏插入圖片描述

4.名稱查找順序

大致順序:
在這裏插入圖片描述
詳細順序:
先從當前所在的名稱空間找,找不到按照大致順序去別的名稱空間找。
eg:在全局代碼中調用變量x,如果沒有就去內置名稱空間找,不會去局部。

實例代碼1:

def func():
    print(format)			#先在局部名稱空間找format,沒找到後去全局名稱空間找,沒找到後去內置名稱空間找
func()

結果如下:
在這裏插入圖片描述
實例代碼2:

def f1():
    print(x)
x = 1
f1()                          結果爲:1

二.作用域

1.認識作用域

作用域:名稱作用有效區域,
將三個名稱空間內名稱的作用區域劃分爲全局作用域和局部作用域。
全局作用域: 內置名稱和全局名稱的作用範圍,全局有效
局部作用域:局部名稱的作用範圍,局部有效

2.globals、locals、global、nonlocal

1.globals與locals
globals():查看全局作用域中的所有名稱
locals():查看當前作用域中的所用名稱,在全局作用域中使用locals結果與globals相同
二者的返回值都是字典

def func1():
	pass
print(globals)

結果如下:
在這裏插入圖片描述

def func():
	x = 2
	print(locals)

結果如下:
在這裏插入圖片描述

2.global、nonlocal

global:聲明是全局作用域中的名稱,如果不存在則創建
nonlocal:聲明是局部作用域的名稱,會調用離自己最近的局部作用域中的名稱,如果沒有再上一層,若局部作用域中找不到則報錯

示例代碼1:

def a():
    class A:
        pass
a()
print(A)				結果爲:<class '__main__.A'>

示例代碼2:

def a():
  a = 1
    def b():
        def c():
            nonlocal a
            print(a)
        c()
    b()
a()						結果爲:1

示例代碼3:

a = 1
def a():
    def b():
        def c():
            nonlocal a
            print(a)
        c()
    b()
a()					結果爲:報錯,因爲局部作用域中不存在a

三.注意

切記:涉及名稱空間的嵌套時,記住函數內調用的名稱是在函數定義時就已經確定了,與調用位置無關。
eg:

x = 2
def func():
	x = 1
	def inner():
		print(x)
	return inner
func()()						結果爲1

四.小練習

input = 333
def func():
    input = 444
func()
print(input)
def func():
    print(x)
x = 111
func()
def func():
    print(x)

def foo():
    x = 222
    func()
x = 333
foo()
x = 111
def func():
    print(type(x))
    x = 222
func()
input = 111
def f1():
    def f2():
        input = 333
        print(input)
    input = 222
    f2()
input = 333
f1()
x = 111
def foo():
    print(x)

def bar():
    print(x)

foo()
bar()
x = 1
def func2():
    func1()
x = 2
def func1():
    print(x)
x = 3
func2()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章