python初學者筆記——命名空間


對於初學者而言,閉包的概念一直都是很難理解的。

我在學習的時候,網上查了那么多資料,依然是一知半解。

直到后來我看了這篇文章:http://simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/

這是一篇很好的文章,由淺入深的告訴你到底閉包,裝飾器都是什么東西。

E文不過關?沒關系,我來用我自己的理解和你們聊聊命名空間、閉包和裝飾器的那些事兒。

前提:

閱讀這篇文章的前提,是你要對Python,有基礎的理解,如果你有興趣,但是對python還沒有理解,我推薦你去讀下面的教程:

www.liaoxuefeng.com

同時,微信公眾號:easypython,中文名:說人話的python分享,也是很不錯的教程,建議有一定入門基礎的同學嘗試。

說人話的python實戰計划:http://study.163.com/course/introduction/1002794001.htm

 

開始:

 

命名空間

命名空間(namespace)這個概念,有時也被稱為“作用域”,在大多數講解閉包的時候都會有所涉及。

那什么是命名空間/作用域呢?

這兩個概念,是用來描述一個變量的屬性的,它們的意思,就是字面意思:“這個變量起名字的地方/這個變量起作用的域”.

我們用實例來說明一下:

def func():
    x = 1

 

 簡單的函數,這個函數定義了一個叫做x的變量,且給了它一個值:1

那么,如果我們print這個變量呢?(我用注釋來表示輸出)

def func():
    x = 1
    print(x)

func()

# 1

好像完全是廢話嘛!print(x)不顯示1,難道還顯示別的?

那好,我們換一種情況,如果我們在函數體外面print(x)呢?

def func():
    x = 1

print(x)

# Traceback 后面一大堆我省略了...
# NameError: name 'x' is not defined

報了一個錯誤,錯誤的類型是name error,名稱錯誤,錯誤的細節是:x沒有定義。

看到這里,細心的朋友應該就知道我說這么多廢話是什么意思啦!

x定義在函數體內部嘛,它的“作用范圍”就僅僅是函數體內才能用!

你想把X打印出來?想把x加1?想把x乘以2?對不起,請到函數體內部去執行,外面,python不認識它。

說到python不認識它,其實是指“python的解釋器”不認識它,解釋器具體不多解釋,你可以簡單的理解為你電腦的python程序。

好吧好吧,python不認識它,那么如果,我換一種情況呢?我把兩個語句交換一下位置?

x = 1

def func():
    print(x)

func()

# 1

咦?你這個騙子,你不是說python不認識它嗎?現在x不在函數體內定義了(事實上函數體內什么定義都沒有~)

你怎么又認識它了?

問到這個問題,就得說一說python程序,讀取一個變量的方法了。

簡單的說,四個字:由內而外

python先去查函數體內部:

1.我找到了,打印!

2.我找不到,我去找外面,找到了,打印!

3.我找不到,我去找外面,我還是找不到! NameError: 我找不到變量,你丫沒定義吧?

看,就是這么個順序。

那么找不到的x變量去哪里了?

比如這個程序:

def func():
    x = 1

print(x)

x呢?x去哪里了?

答案是x被python解釋器給“回收”了,所謂回收,你可以簡單的理解成刪除了、殺死了。

這里要引入一個概念,就是變量的“存活時間”

我寫一下你就了解了(為了方便的標記函數體的結束,我寫了一個返回字符串‘done’的return語句):

def func():
    
    x = 1  
    # x的存活時間開始,在x=1這行下面操作x才可以!
    
    return 'Done'  # 函數體結束,x被python殺死了。

就是如上代碼中所表述的意思:

一個函數體內變量的存活時間,從定義它的那一刻開始,直到函數體結束為止。

我們可以通過一個很方便的、python給定我們的方法,來判斷函數體內部還“活着”的變量有哪些,這個方法是locals()

我們看一個代碼:

def func():

    a = '哎呀'
    b = '我們'
    c = '還活着'
    print(locals())


func()

# {'a': '哎呀', 'c': '還活着', 'b': '我們'}

看,locals()其實是一個字典,他列出了所有的“變量:變量值”這樣的“鍵-值對”,而且字典是無序的。

locals()里面存的全部都是當前“活着”的變量,我們看另外一個例子:

def func():

    a = '哎呀'
    b = '我們'
    c = '還活着'
    print(locals())
    d = '我還沒出生'


func()

# {'b': '我們', 'c': '還活着', 'a': '哎呀'}


看,locals()里面就沒有變量d什么事情了,因為d在那個時候“還沒出生”呢。

那么外部的變量呢?

x = 1
def func():

    a = '內部'
    print(locals())
    print(x)


func()

# {'a': '內部'}
# 1


看到了吧,內部變量只有一個,locals也打印出來了,但是x還是正常的可以打印。

因為python在內部找不到,於是就去外面找了,外部的變量,可以用globals()檢查到,但是這個很長…………

x = 1
def func():

    a = '內部'
    print(locals())
    print(globals())


func()

# {'a': '內部'}
# ....(一大堆我就不粘貼了)..... 'x': 1}

命名空間/作用域的概念就是這樣,它決定了python程序“去哪里”找到變量。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM