變數作用域(scope)在python中是乙個容易掉坑的地方。
python的作用域一共有4中,分別是:
以l --> e --> g -->b的規則查詢,即:在區域性找不到,便會去區域性外的區域性找(例如閉包),再找不到就會去全域性找,再者去內建中找。python除了def/class/lambda
外,其他如:if/elif/else/ try/except for/while
並不能改變其作用域。定義在他們之內的變數,外部還是可以訪問。
在>>> if true:
... a = 'i am a'
...
>>> a
'i am a'
# 定義在if語言中的變數a,外部還是可以訪問的。
# 但是需要注意如果if被 def/class/lambda 包裹,在內部賦值,就變成了此 函式/類/lambda 的區域性作用域。
def/class/lambda
內進行賦值,就變成了其區域性的作用域,區域性作用域會覆蓋全域性作用域,但不會影響全域性作用域。
g = 1 #全域性的
def fun():
g = 2 #區域性的
return g
print fun()
# 結果為2
print g
# 結果為1
但是要注意,有時候想在函式內部引用全域性的變數,疏忽了就會出現錯誤,比如:
在未被賦值之前引用的錯誤!為什麼?因為在函式的內部,直譯器探測到var被重新賦值了,所以var成為了區域性變數,但是在沒有被賦值之前就想使用var,便會出現這個錯誤。解決的方法是在函式內部新增#file1.py
var = 1
def fun():
print var
var = 200
print fun()
#file2.py
var = 1
def fun():
var = var + 1
return var
print fun()
# 這兩個函式都會報錯unboundlocalerror: local variable 'var' referenced before assignment
globals var
但執行函式後全域性的var也會被修改。
閉包的定義:如果在乙個內部函式裡,對在外部函式內(但不是在全域性作用域)的變數進行引用,那麼內部函式就被認為是閉包(closure)
函式巢狀/閉包中的作用域:
一樣會報錯- 引用在賦值之前,python3有個關鍵字a = 1
def external():
global a
a = 200
print a
b = 100
def internal():
# nonlocal b
print b
b = 200
return b
internal()
print b
print external()
nonlocal
可以解決這個問題,但在python2中還是不要嘗試修改閉包中的變數。
關於閉包中還有乙個坑:
也會出現 引用在賦值之前 的錯誤,原因是直譯器探測到了from functools import wraps
def external(f):
@wraps(f)
def internal(**kw):
if false:
log = 'modified'
print log
return internal
return external
def abc():
pass
print abc()
if false
中的重新賦值,所以不會去閉包的外部函式(enclosing)中找變數,但if flase
不成立沒有執行,所以便會出現此錯誤。除非你還需要else: log='var'
或者if true
但這樣新增邏輯語句就沒了意義,所以盡量不要修改閉包中的變數。
好像用常規的方法無法讓閉包實現計數器的功能,因為在內部進行count +=1
便會出現 引用在賦值之前 的錯誤,解決辦法:(或py3環境下的nonlocal
關鍵字)
由於def counter(start):
count =[start]
def internal():
count[0] += 1
return count[0]
return internal
count = counter(0)
for n in range(10):
print count()
# 1,2,3,4,5,6,7,8,9,10
count = counter(0)
print count()
# 1
list
具有可變性,而字串是不可變型別。
global
和globals()
是不同的,global
是關鍵字用來宣告乙個區域性變數為全域性變數。**globals()
和locals()
**提供了基於字典的訪問全域性和區域性變數的方式
比如:如果函式1內需要定義乙個區域性變數,名字另乙個函式2相同,但又要在函式1內引用這個函式2。
如果你使用過python的web框架,那麼你一定經歷過需要把乙個檢視函式內很多的區域性變數傳遞給模板引擎,然後作用在html上。雖然你可以有一些更聰明的做法,還你是仍想一次傳遞很多變數。先不用了解這些語法是怎麼來的,用做什麼,只需要大致了解locals()是什麼。def var():
pass
def f2():
var = 'just a string'
f1 = globals()['var']
print var
return type(f1)
print f2()
# just a string
#
可以看到,locals()把區域性變數都給打包一起扔去了。
#或者 return render_template('index.html', **locals())
python變數作用域
變數作用域 scope 在python中是乙個容易掉坑的地方。什麼是作用域 作用域簡單說就是乙個變數的命名空間。中變數被賦值的位置,就決定了哪些範圍的物件可以訪問這個變數,這個範圍就是命名空間。python賦值時生成了變數名,當然作用域也包括在內。python的作用域一共有4中,分別是 l loca...
Python 變數作用域
g global defchange global g g g change print g change print g 結果 global globalchange def function g function deflocalvar g local defglobalvar global g...
變數作用域 python
python 中,程式的變數並不是在哪個位置都可以訪問的,訪問許可權決定於這個變數是在 賦值的。變數的作用域決定了在哪一部分程式可以訪問哪個特定的變數名稱。python的作用域一共有4種,分別是 以 l e g b 的規則查詢,即 在區域性找不到,便會去區域性外的區域性找 例如閉包 再找不到就會去全...