Python基础-作用域和命名空间(Scope and Namespace)
在Python中,對象是獨(dú)立的,不同作用域中的不同名字都可以被綁定在同一個(gè)對象上,當(dāng)然對這個(gè)對象的修改會(huì)影響所有的引用。賦值操作就是名字和對象的綁定或重綁定。這和C++中的引用是一樣的。
1,基礎(chǔ)概念
1.1 命名空間(namespace) ?
A?namespace?is a mapping from names to objects
命名空間是名字和對象的映射。也就是可以把一個(gè)namespace理解為一個(gè)字典,實(shí)際上很多當(dāng)前的Python實(shí)現(xiàn)namespace就是用的字典。各個(gè)命名空間是獨(dú)立的,沒有任何關(guān)系的,所以一個(gè)命名空間中不能有重名,但不同的命名空間是可以重名而沒有任何影響。
那么哪些可以是一個(gè)namespace呢,比如Python的built-in names(包括內(nèi)置函數(shù),內(nèi)置常量,內(nèi)置類型);一個(gè)模塊的global names(這個(gè)模塊定義的函數(shù),類,變量);一個(gè)函數(shù)的所有l(wèi)ocal names;還有一個(gè)類對象的所有屬性(數(shù)據(jù)成員,成員函數(shù))都組成一個(gè)命名空間。
命名空間都是有創(chuàng)建時(shí)間和生存期的。對于Python built-in names組成的命名空間,它在Python解釋器啟動(dòng)的時(shí)候被創(chuàng)建,在解釋器退出的時(shí)候才被刪除;對于一個(gè)Python模塊的global namespace,它在這個(gè)module被import的時(shí)候創(chuàng)建,在解釋器退出的時(shí)候退出;對于一個(gè)函數(shù)的local namespace,它在函數(shù)每次被調(diào)用的時(shí)候創(chuàng)建,函數(shù)返回的時(shí)候被刪除。
[總結(jié)]一個(gè)模塊的引入,函數(shù)的調(diào)用,類的定義都會(huì)引入命名空間,函數(shù)中的再定義函數(shù),類中的成員函數(shù)定義會(huì)在局部namespace中再次引入局部namespace。
?
1.2 作用域(scope) ?
A?scope?is a textual region of a Python program where a namespace is directly accessible.
作用域是Python程序(文本)的某一段或某些段,在這些地方,某個(gè)命名空間中的名字可以被直接引用。這個(gè)作用域就是這個(gè)命名空間的作用域。
一個(gè)Python程序的幾個(gè)作用域:
?
關(guān)于作用域,參加Python基礎(chǔ)-函數(shù)這片博客中2小節(jié)的例子。
?
1.3 賦值(assignment) ?
Assignments do not copy data — they just bind names to objects.
賦值操作不會(huì)拷貝,只是把名字和對象做一個(gè)綁定。也就是賦值語句是起一個(gè)綁定或重綁定的作用(bind or rebind)。函數(shù)調(diào)用的參數(shù)傳遞是賦值,不是拷貝。
?
2,global和nonlocal語句
global語句用來聲明一系列變量,這些變量會(huì)引用到當(dāng)前模塊的全局命名空間的變量(module-level namespace),如果該變量沒有定義,也會(huì)在全局空間中添加這個(gè)變量。
global var1, var2?nonlocal語句(nonlocal是Python3.2引入的)
Python2.7中還沒有nonlocal語句。nonlocal語句用來聲明一系列的變量,這個(gè)聲明會(huì)從聲明處從里到外的namespace去搜尋這個(gè)變量(the nearest enclosing scope),直到模塊的全局域(不包括全局域),找到了則引用這個(gè)命名空間的這個(gè)名字和對象,若作賦值操作,則直接改變外層域中的這個(gè)名字的綁定。nonlocal語句聲明的變量不會(huì)在當(dāng)前scope的namespace字典中加入一個(gè)key-value對,如果在外層域中沒有找到,則如下報(bào)錯(cuò)。
>>>SyntaxError: no binding for nonlocal 'spam' found
?
?一個(gè)nonlocal和global的測試?yán)?/p> 1 def test():
2 def do_local():
3 spam = "local spam"
4 def do_nonlocal():
5 nonlocal spam
6 spam = "nonlocal spam"
7 def do_global():
8 global spam
9 spam = "global spam"
10 spam = "test spam"
11 do_local()
12 print("after local assignment:", spam) #輸出:test spam
13 do_nonlocal()
14 print("after nonlocal asssignment:", spam) #輸出:nonlocal spam
15 do_global()
16 print("after global assignment:", spam) #輸出:nonlocal spam
17
18 test()
19 print("in global scope:", spam) #輸出:global spam
第5行的語句:nonlocal spam 沒有在函數(shù)do_nonlocal()的域中創(chuàng)建一個(gè)變量,而是去引用到了外層的,10行定義的spam。
第8行的global spam,在全局域中創(chuàng)建了一個(gè)name,9行將其綁定在字符串常量對象"global spam"上。
?
跟進(jìn)一步測試nonlocal
1 def test(): 2 def do_nonlocal(): 3 nonlocal spam 4 def do_nonlocal2(): 5 nonlocal spam 6 spam = "nonlocal2 spam" #修改了test()中spam的綁定 7 do_nonlocal2() 8 spam = "test spam" 9 do_nonlocal() 10 print("after nonlocal2 asssignment:", spam) #輸出:nonlocal2 spam 11 test()do_nonlocal2()中的spam引用的是其外面的二層,也就是test()函數(shù)域中的spam。
?
?
參考:
http://docs.python.org/3.3/tutorial/classes.html#python-scopes-and-namespaces? ?Python文檔
http://docs.python.org/3.2/reference/simple_stmts.html? Python文檔-simple statement
轉(zhuǎn)載于:https://www.cnblogs.com/livingintruth/p/3296010.html
總結(jié)
以上是生活随笔為你收集整理的Python基础-作用域和命名空间(Scope and Namespace)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Maven 引入 ojdbc:ojdbc
- 下一篇: python 数据分析实践--(1)收入