python學習筆記——模塊和命名空間

(以下基本摘自《王純業的python學習筆記》,所有命令均測試通過)

  

    模塊(module)是Python中非常重要的一個概念,模塊其實就一些函數和類的集合文件,它能實現一些相應的功能,當我們需要使用這些功能的時候,直接把相應的模塊導入到我們的程序中,我們就可以使用了。這類似於C語言中的include頭文件,Python中我們用import導入我們需要的模塊。

    類似於頭文件,模塊也是需要系統的搜索路徑的,下面的命令即是系統默認的搜索路徑,當你導入一個模塊時,系統就會在下面的路徑列表中搜索相應的文件。

>>> sys.path

['C:/Python26/code', 'C:\\Python26\\Lib\\idlelib', 'C:\\WINDOWS\\system32\\python26.zip', 'C:\\Python26\\DLLs', 'C:\\Python26\\lib', 'C:\\Python26\\lib\\plat-win', 'C:\\Python26\\lib\\lib-tk', 'C:\\Python26', 'C:\\Python26\\lib\\site-packages', 'C:\\Python26\\lib\\site-packages\\win32', 'C:\\Python26\\lib\\site-packages\\win32\\lib', 'C:\\Python26\\lib\\site-packages\\Pythonwin', 'C:\\Python26\\lib\\site-packages\\wx-2.8-msw-unicode']

    假如沒有搜到相應內容就會報錯。

>>> import xxx

 

Traceback (most recent call last):

  File "<pyshell#104>", line 1, in <module>

    import xxx

ImportError: No module named xxx

    當然我們也可以添加我們的搜索路徑。調用列表的append方法即可。

sys.path.append(‘相對路徑或者絕對路徑’)

    然後我們就可以加載我們自己的模塊了。那麼如何創建我們自己的模塊呢,簡單看一下。首先我們在當前目錄創建一個名爲testmodule.py的文件,內容如下:

"""

this only is a very simple test module

"""

age=0 # a simple attribute

def sayHello(): # a simple function in a module

    print 'Hello'

if __name__=="__main__":

    sayHello()

    然後我們導入這個模塊就可以使用它的變量和函數了。

>>> import test_module

>>> test_module.age

0

>>> test_module.sayHello()

Hello

>>>

   當然我們也可以這樣:

>>> from test_module import age,sayHello

>>> age

0

>>> sayHello

<function sayHello at 0x012DF430>

>>> sayHello()

Hello

>>> test_module

 

Traceback (most recent call last):

  File "<pyshell#138>", line 1, in <module>

    test_module

NameError: name 'test_module' is not defined

>>> 

    注意兩種方法的不同。 From 並沒有把test_module 引進來,所以當前namespace沒有test_module這個name。所以報錯。

 

    命名空間(name space)是從名稱(name)到對象(object)的映射(map)。當一個name映射到一個object上時,這個name和這個object就綁定(bind)了。

    Python中一切都是對象(object),包括function,module,class,package本身。這些對象都在內存中真正的存在,就 像活在世上的每一個人。但是我們怎麼找到這些object呢?用name給每個object起名。每個名字只對應一個對象,一個對象可以由多個名字。但是 name不是object本身。

Python中有很多name space,常用的有:build—in name space(內建命名空間)global name space(全局命名空間),local name space(局部命名空間)。在不同的name space中的name是沒有關係的。

每個object都有自己的name space,可以通過object.name的方式訪問object的name space中的name,每個object的name都是獨立。即使在別的name space中有與之相同的name,它們也是沒有任何關聯的。

每一個object,都有自己的name space,name space都是動態創建的,每一個name space的生存時間也不一樣。

    一個模塊的name space是這個module被import的時候創建的。每個module都有一個_name_的attribute,用來表示當前module的名字。所以每個module都有這樣的代碼:

If _name_= = “_main_”:

   sayHello()  #測試代碼

   下面是測試代碼

>>> import sys

>>> sys.path.append('C:\Python26\code')

>>> sys.path

['C:\\Python26\\Lib\\idlelib', 'C:\\WINDOWS\\system32\\python26.zip', 'C:\\Python26\\DLLs', 'C:\\Python26\\lib', 'C:\\Python26\\lib\\plat-win', 'C:\\Python26\\lib\\lib-tk', 'C:\\Python26', 'C:\\Python26\\lib\\site-packages', 'C:\\Python26\\lib\\site-packages\\win32', 'C:\\Python26\\lib\\site-packages\\win32\\lib', 'C:\\Python26\\lib\\site-packages\\Pythonwin', 'C:\\Python26\\lib\\site-packages\\wx-2.8-msw-unicode', 'C:\\Python26\\code']

>>> import test_module

>>> dir(test_module)

['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'age', 'sayHello']

>>> test_module.__name__

'test_module'

>>> 

    我們看到這個module有一個__name__屬性。因爲這個module在被import的時候,它的name space中創建了一個內置的name ,__name__,用來表示module的文件名稱。所以import的時候,測試代碼sayHello()並沒有運行,因爲if條件不滿足。但是如果我們直接運行該模塊的話,那麼module的name space就是global name space,這時Python自動把global name space中的__name__ 設爲__main__,測試代碼就會運行,打印出Hello。

 

    當調用一個function的時候,function的local name space被創建了,當function返回的時候或者異常中斷的時候,local name space被刪除了。

 

    作用域(scope),是python中的代碼從字面意義上可以直接訪問的name集合。

LGB的規則用scope的概念來解釋就是:和任何代碼執行的時候,都至少有三個scope:local name space,global name space ,buildin name space (LGB)。看下面的例子:

>>> def sayHello():

       print 'Hello'

 

>>> saidHello=sayHello

>>> saidHello

<function sayHello at 0x012DFE30>

>>> sayHello

<function sayHello at 0x012DFE30>

>>> sayHello()

Hello

>>> saidHello()

Hello

>>> 

    可以看到sayHello和saidHello不過是兩個名字,他們都是指的同樣的object,就像一個人有兩個名字一樣。

用del可以從一個name space刪除一個name,如:

>>> a=1

>>> b=a

>>> a

1

>>> b

1

>>> id(a)

11364056

>>> id(b)

11364056

>>> del a

>>> a

 

Traceback (most recent call last):

  File "<pyshell#27>", line 1, in <module>

    a

NameError: name 'a' is not defined

>>> b

1

    可以看到a和b指向同一個object,然後我們del a,只是從name space清除了一個name和object的綁定關係,如果沒有其他name和這個對象bind,那麼纔是真正的清除object。實際上python中使用了智能指針技術,每個name都和指向object的指針相關聯,每一個object都有一個reference counter記住有多少個name和這個object相關聯。每次bind,reference counter都加1,每次刪除bind,都減1,只有當reference counter爲0時,object才真正被刪除。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章