python學習手冊17作用域
點選(此處)摺疊或開啟
-
#!/usr/bin/env python
- #–*– coding:utf8 –*–
- #python對變數的操作都是在名稱空間中(作用域),變數名被賦值的位置決定了這個變數名能被訪問到的範圍。
- #變數賦值的地方決定了名稱空間,即語義作用域。
- #一個函式所有變數名都與函式的名稱空間相關。
-
“`
- def內定義的變數名只能在def內使用。
- def內外的變數名不衝突。
- 變數對應的作用域: 作用於可以防止程式變數名衝突。
- def內賦值就是def內。
- 巢狀def,對於巢狀函式是非本地。
- def外賦值,是全域性的。
- `“
- X=99#全域性變數
- def func():
- X=88 #函式本地變數
- #函式定義了本地作用哉,模組定義了全域性作用域。
-
“`
- 內嵌的模組是全域性作用域。
- 全域性作用域的範圍僅限單個檔案。(全域性是相對一個模組或檔案而言。)
- 每次對函式的呼叫都建立了一個新的本地作用域。
- 賦值的變數名除非宣告為全域性變數或本地變數,否則均為本地變數。
- 所有其它的變數名都可以歸納為本地、全域性、或都內建的。
- 此外,原處改變物件並不會把變數劃分為本地變數,只有對變數名賦值才可以。即修改一個物件並不是對一個名稱賦值。
- `“
- print(`變數名解析:LEGB原則`)
-
“`
- 變數名按:本地(L)->上層函式(E)->全域性(G)->內建(B)的順序查詢
- 預設變數名賦值會建立或改變本地變數。(賦值總是建立或改變變數名,除非宣告過型別。)
- 全域性宣告與非本地宣告將賦值變數名對映到模組內部的作用域。
- `“
- #全域性變數
- X=99 #X與func在本模組中是:全域性變數
- def func(Y): #Y與Z在函式中是本地變數
- #本地變數
- Z=X+Y #X是全域性變數
- return Z
- print(func(1))
- #內建作用域 __builtin__ 內建模組
- #import __builtin__
- #print(dir(__builtin__))
- #global語句
-
“`
- 全域性變數是位於模組檔案內部頂層的變數
- 全域性變數在函式內必須經過宣告
- 全域性變數在函式內不用宣告可以引用
- `“
- X=88 #全域性變數
- def func():
- global X #全域性變數宣告
- X=99
- return X
- print(func())
- print(X)
- a,b=1,2
- def all_global():
- global x
- x=a+b
- print(x)
- all_global()
- print(x)
- #最小化全域性變數
- #原因是:流程控制比較難,儲存狀態資訊過於複雜。
- #最小化檔案間的修改
- #隱性的跨檔案依賴性,在最好的情況下會導致程式碼不靈活,最壞的情況會引發bug。
- import t17mod
- t17mod.test()
- #這個例子表明全域性變數與模組的屬性是等效的。但比global要多寫許多語句。
-
“`
- 作用域和巢狀函式
- `“
- #按照LEGB法測,如果巢狀函式將一個變數宣告為全域性變數,它將改變整個模組作用域。如果我們只想想必被巢狀函式同為此變數名的變數的作用域,可以使用nonlocal宣告,賦值會修改最近的巢狀函式中的變數的作用域
- print(`作用域和巢狀函式`)
- TT=99 #全域性作用
- def f1():
- TT=88 #本地作用
- def f2(): #f2是f1函式的本地變數
- print(TT) #根據LEGB法則,X=88
- f2()
- f1()
- #工廠函式,一個能記住巢狀作用域的變數值的函式,雖然有可能那個作用域已經不存在了。但類是最適合做記憶狀態的。
- #本地作用域中N被作為執行的狀態資訊保留下來。
- def maker(N):
- def action(M):
- return N*M
- return action
- f = maker(5) #N=5
- print(f(2)) #M=2,N是被記憶的為5
- #新建立的函式不影響原來的
- g=maker(9)
- print(g(2))
- print(f(2))
-
“`
- 儘量避免在def中內巢狀def。只要第二個函式定義在第一個函式呼叫前就可行。
- 如此可以避免使用巢狀
- `“
- def f1():
- x=100
- f2(x)
- def f2(x):
- print(x)
- f1()
-
“`
- 巢狀作用域和lambda
- lambda是一個表示式,但類似def,會生成新的作用域,可以使用在def不能使用的地方,如一個列表或是字典中
- `“
- def func(N):
- action=(lambda M : N ** M)
- return action
- A=func(5)
- print(A(2))
- print(func(5)(3))
-
“`
- 作用域與帶有迴圈變數的預設引數相比較
- lambda或def函式在一個函式中定義,巢狀在一個迴圈中,並引用了上層函式的一個變數,變數在迴圈中被改變,但lambda或def函式最後值是最後一次迴圈後的值,不會受其它迴圈值影響
- `“
- def makeAction():
- acts = []
- for i in range(5):
- acts.append(lambda n : i ** n )
- return acts
- actss=makeAction()
- print(actss[2](2))
- #因此必須把巢狀函式的值傳遞給巢狀作用域的變數
- def makeAction2():
- acts = []
- for i in range(5):
- acts.append(lambda n, i=i: i ** n)
- return acts
- actsss=makeAction2()
- print(actsss[3](2))
- #actsss[i]i最大不能超過range(5)的最大值。
- print(actsss[4](2))
-
“`
- 作用域可以被任意巢狀,但是隻有內嵌的函式會被搜尋。
- 在python中,平坦優於巢狀。
- `“
-
“`
- nonlocal允許對巢狀函式作用域中的名稱賦值,並且把這樣的名稱作用域查詢限制在巢狀def.
- `“
- def tester(start):
- state=start
- def nester(label):
- #預設不允許修改巢狀的def作用域中的名稱。
- #state +=1 #UnboundLocalError: local variable `state` referenced before assignment
- #python3.0中使用nonlocal修改,前提是nonlocal的變數在上層函式中已經賦值過。
- #nonlocal只在上層函式的作用域中查詢變數,不會去其它作用域查詢。
- #nonlocal state
- #nonlocal nostate #SyntaxError: no binding for nonlocal `nostate` found
- print(label,state)
- #state +=50
- return nester
- F=tester(100)
- F(111) #111 100
- F(112) #112 150
- #如果建立一個新的副本,不會影響原來的state
- G=tester(10)
- G(`egg`) #egg 10
- G(`egg2`) #egg2 60
- F(`old`) #old 200
- states2 = 9
- def tester2(start):
- def nester2(lable):
- global states2
- states2 = 99
- print(lable,states2)
- return nester2
- H=tester2(1000)
- H(`new`) #new 99
- #nonlocal語句允許在內在保持可變狀態的多個副本,並且解決了在類無法保證的情況下的簡單的狀態保持。
- #下面使用類實現存狀態保持。
- class ctest:
- def __init__(self,A):
- self.state = A
- def funcA(self,label):
- print(label,self.state)
- self.state +=1
- CL=ctest(88)
- CL.funcA(`egg`) #(`egg`, 88)
- CL.funcA(`egg2`) #(`egg2`, 89)
- print(CL.state) #90
- #使用__call__運算子過載工具獲取一個例項上的直接呼叫
- class ct:
- def __init__(self,A):
- self.state = A
- def __call__(self,label):
- print(label,self.state)
- self.state +=11
- CL1=ct(77)
- CL1(`python`) #(`python`, 77)
- CL1(`ADD11`) #(`ADD11`, 88)
- #下面這個沒搞通,再研究了。
-
“`
- def Z(start):
- def Y(lable):
- print(lable,Y.state)
- Y.state += 1
- Y.state = start
- return Y
- X=Z(188)
-
X(`egg`)
- `“
-
“`
- 全域性、非本地、類、函式屬性都提供了狀態保持選項。
- 全域性只支援共享資料,類要用OOP知識,類和函式屬性都允許巢狀自身之外訪問狀態。最好的工具取決於程式的目的。
- `“
t17mod.py
點選(此處)摺疊或開啟
-
#!/usr/bin/env python
- #coding:utf8
- var=99 #全域性變數=模組屬性
- def local():
- var = 0 #本地變數,不影響
- def glob1():
- global var #全域性變數
- var +=1 #修改全域性var=100
- def glob2():
- var =0
- import t17mod #匯入模組,變成模組屬性
- t17mod.var +=1
- def glob3():
- var = 0
- import sys
- glob = sys.modules[`t17mod`] #對模組屬性生新賦值
- glob.var +=1
- def test():
- print(var)
- local();glob1();glob2();glob3() #按照執行順序,第一個函式不影響全域性變數
- print(var)
結果
點選(此處)摺疊或開啟
-
/usr/bin/python2.7 /home/talen/PycharmProjects/untitled/t17.py
- 變數名解析:LEGB原則
- 100
- 99
- 99
- 3
- 3
- 99
- 102
- 作用域和巢狀函式
- 88
- 10
- 18
- 10
- 100
- 25
- 125
- 16
- 9
- 16
- (111, 100)
- (112, 100)
- (`egg`, 10)
- (`egg2`, 10)
- (`old`, 100)
- (`new`, 99)
- (`egg`, 88)
- (`egg2`, 89)
- 90
- (`python`, 77)
- (`ADD11`, 88)
- Process finished with exit code 0
相關文章
- Python 學習之作用域Python
- Python學習手冊Python
- Python學習筆記 - 作用域Python筆記
- python學習手冊(10)Python
- python學習手冊(8)Python
- python學習手冊(4)Python
- 學習JavaScript作用域JavaScript
- python學習筆記 區域性和全域性作用域Python筆記
- Vue學習(十一)——作用域Vue
- Redux學習手冊Redux
- ITIL學習手冊
- 深入學習js之——詞法作用域和動態作用域JS
- Python學習手冊之類和繼承Python繼承
- Python學習手冊之控制結構(二)Python
- Python學習手冊(第4版)PDF版Python
- python學習手冊13:while及for迴圈PythonWhile
- Spring學習(二)Bean 作用域SpringBean
- 深入學習js之——詞法作用域和動態作用域#2JS
- Beautiful Soup 學習手冊
- PostgreSQL學習手冊(索引)SQL索引
- 深入學習js之——作用域鏈#5JS
- Python 3 學習筆記之——變數作用域、模組和包Python筆記變數
- Python學習手冊(入門&爬蟲&資料分析&機器學習&深度學習)Python爬蟲機器學習深度學習
- Python學習手冊之Python介紹、基本語法(一)Python
- 【python學習手冊】02|使用Python提取中文關鍵詞?Python
- SQLite學習手冊(目錄)SQLite
- PostgreSQL學習手冊(模式Schema)SQL模式
- Linux學習手冊(轉)Linux
- python學習手冊25OOP:巨集偉藍圖PythonOOP
- python-作用域Python
- python學習筆記:第10天 函式進階和作用域Python筆記函式
- web前端學習教程:JS的作用域鏈Web前端JS
- Mybatis學習-配置、作用域和生命週期MyBatis
- 《Python機器學習手冊:從資料預處理到深度學習》Python機器學習深度學習
- Python學習手冊之捕獲組和特殊匹配字串Python字串
- [python學習手冊-筆記]004.動態型別Python筆記型別
- [python學習手冊-筆記]003.數值型別Python筆記型別
- Redis學習手冊(Key操作命令)Redis