Spring擴展 1.自定義攔截器 spring mvc攔截器根spring攔截器相比,它裡面能夠獲取HttpServletRequest和HttpServletResponse等web對象實例。 spring mvc攔截器的頂層介面是:HandlerInterceptor,包含三個方法: preH ...
函數內部的函數只能在函數內部調用,不能在函數外部調用,通過接下來的學習你將會知道為什麼會出現這種情況。
def f1():
def f2():
print('from f2')
f2()
f2() # NameError: name 'f2' is not defined
一、名稱空間
名稱空間(name spaces):在記憶體管理那一章節時,我們曾說到變數的創建其實就是在記憶體中開闢了一個新的空間。但是我們一直在迴避變數名的存儲,其實在記憶體中有一塊記憶體存儲變數名與變數間的綁定關係的空間,而這個空間稱為名稱空間。
1 內置名稱空間
內置名稱空間:存放Pyhton解釋器自帶的名字,如int、float、len
生命周期:在解釋器啟動時生效,在解釋器關閉時失效
2 全局名稱空間
全局名稱空間:除了內置和局部的名字之外,其餘都存放在全局名稱空間,如下麵代碼中的x、func、l、z
生命周期:在文件執行時生效,在文件執行結束後失效
x = 1
def func():
pass
l = [1, 2]
if 3 > 2:
if 4 > 3:
z = 3
3 局部名稱空間
局部名稱空間:用於存放函數調用期間函數體產生的名字,如下麵代碼的f2
生命周期:在文件執行時函數調用期間時生效,在函數執行結束後失效
def f1():
def f2():
print('from f2')
f2()
f1()
4 載入順序
由於.py文件是由Python解釋器打開的,因此一定是在Python解釋器中的內置名稱空間載入結束後,文件才開始打開,這個時候才會產生全局名稱空間,但文件內有某一個函數被調用的時候,才會開始產生局部名稱空間,因此名稱空間的載入順序為:內置--》全局--》局部。
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()
輸出
10
二、作用域
域指的是區域,作用域即作用的區域。
1 全局作用域
全局作用域:全局有效,全局存活,包含內置名稱空間和全局名稱空間。
# 全局作用域
x = 1
def bar():
print(x)
bar()
輸出
1
2 局部作用域
局部作用域:局部有小,臨時存儲,只包含局部名稱空間。
# 局部作用域
def f1():
def f2():
def f3():
print(x)
x = 2
f3()
f2()
f1()
輸出
2
3 註意點
需要註意的是:作用域關係在函數定義階段就固定死了,與函數的調用無關。
# 作用域註意點
x = 1
def f1(): # 定義階段x=1
print(x)
def f2():
x = 2
f1()
f2()
輸出
1
4 函數對象+作用域應用
# 作用域應用
def f1():
def inner():
print('from inner')
return inner
f = f1() # 把局部定義的函數放在全局之中
def bar():
f()
bar()
輸出
from inner
三、補充知識點
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
2 nonlocal關鍵字
修改局部作用域中的變數。
x = 1
def f1():
x = 2
def f2():
# nonlocal x
x = 3
f2()
print(x)
#學習中遇到問題沒人解答?小編創建了一個Python學習交流群:711312441
f1()
輸出
2
x = 1
def f1():
x = 2
def f2():
nonlocal x
x = 3
f2()
print(x)
f1()
輸出
3
3 註意點
在局部想要修改全局的可變類型,不需要任何聲明,可以直接修改。
在局部如果想要修改全局的不可變類型,需要藉助global聲明,聲明為全局的變數,即可直接修改。
lis = []
def f1():
lis.append(1)
print(f"調用函數前: {lis}")
f1()
print(f"調用函數後: {lis}")
輸出
調用函數前: []
調用函數後: [1]