pythonnamespace
Ⅰ python 中regular package 和 namesapce package的區別
regular package就是指常規模塊,一般就是指python內置模塊例如os,或者使用第三方的插件導入的模塊,例如操作excel的xlrd.沒有所處環境的區別.
namespace package 一般是指用戶自己定義的,為了避免重名沖突,而進行劃分的一種方式.也就是為了實現,在不同環境下,導入不同的模塊,但是為了方便切換,在不同模塊下具有相同變數名稱.常用的情況如,在測試環境和生產環境下,導入定義資料庫配置的全局變數,MYsql_SETTINGS,但是在不同環境下,它所對應的mysql資料庫的配置時不同的.這時就可以通過namespace package來實現.將配置和代碼進行解耦.
實現方式可以有:
不同環境下設置環境變數
程序加入運行參數,導入不同路徑下的配置文件
等等
歡迎補充
Ⅱ python命名空間包導入演算法
要理解命名空間包,需從底層去學習包導入操作在Python 3.3中是如何完成的。在導入過程中,3.3版本與3.2和之前的版本一樣,依舊會遍歷模塊搜索路徑sys.path中的每個目錄。然而,在3.3版本中,當對每個模塊搜索路徑中的directory搜索名為spam的被導人包時,Python會按照下面的順序測試一系列更廣的匹配條件:
1.如果找到directory\spaml_init__.py,便會導入一個常規包並返回。
2.如果找到directoryspam.ipy,pyc,或其他模塊擴展名},便會導人一個簡單模塊並
返回。
3.如果找到文件夾directorylspam,便會將其記錄下來,而掃描將從搜索路徑中的下一
個目錄繼續。
4.如果上述的所有都沒有找到,掃描將從搜索路徑中的下一個目錄繼續。
如果搜索路徑掃描結束後沒有從上述步驟1和步驟2中返回一個模塊或包,而同時在上述步驟3中至少記錄了一個路徑,那麼就會創建一個命名空間包。
命名空間包的創建會立即發生,而且不會推遲到一個子層級的導入發生之時。新的命名空間包有一個_path_屬性,該屬性被設置為在上述步驟3中掃描並記錄的目錄路徑字元串的可迭代對象,但是沒有_file_屬性。
path_屬性在隨後更深的訪問過程中用於搜索所有包組件。命名空間包的_path_中每個被記錄的項目,都會在進一步嵌套的項目被請求時進行搜索,這很像一個常規包的單獨路徑。
從另一方面看,命名空間包的_path_屬性對於更低層次組件的關系,和sys.path對於頂層最左側的包導入路徑的關系是一樣的。命名空間包成為了訪問更低層次項目的「父路徑」,這一訪問也使用了上面介紹的四個步驟。
最終的結果是一個命名空間包是一種對多個目錄的虛擬拼接,這些目錄可以位於多個sys.path項目中。然而一旦一個命名空間包被創建,它和一個常規包之間並沒有功能上的區別,它能夠支持我們所學過的常規包的一切功能,包括包相對導入語法。
Ⅲ Python之禪中的namespace怎麼理解
什麼時候分別用一、二、三是最佳實踐?——這個問題沒有特別的規定,只是看個人編碼風格和習慣。
這三種的定義你應該明白,二和三是一樣的,只是三用了一個通配符導入了模塊中所有名字而已。
命名空間的本質就是採用更長的字元串來區分不同模塊下可能同名的函數/類,然後為了減少寫函數名/類名時候的麻煩,發明的一種可以認為是語法糖的東西。
在一個函數的 scope 的中再定義函數——我本人不常用這種做法,因為我是學C語言出身,一個函數的scope中再定義一個函數,我看到的唯一好處就是可以隱藏一些僅僅由這個函數使用而其他函數不使用的一些小函數,而且不用再傳參數:
def fun(a, b):
def calc(): return a * b - a / b if a < b: return calc() if a >= b: return 1 + calc()
calc函數不用傳參,方便使用,而且對外是隱藏的,這么奇葩的函數在fun外也沒有人用,放到fun內部是比較合適的。當然,也不絕對,你可以愛怎麼寫怎麼寫。
Ⅳ Python 中作用域與命名空間的問題
i=2這一句是定義了一個局部變數i,並賦值為2;這個時候全局作用域的i會被屏蔽,所以全局變數i是沒有被修改的所以結果是1;
訪問全局變數時可以直接訪問,但是修改全局作用域的時候一定要在賦值之前,進行如下聲明:
deff():
globali
i=2
因為python里賦值語句和聲明變數是一個體的,所以需要global來告訴解釋器i是全局變數,接下來的i=2才能被當作是賦值
------------------追答---------------------
同一個代碼塊(作用域)里, 同一個變數的作用域只能是同一種或者說同一個變數只能來自同一個作用域, 不能是一會是局部變數然後又變成全局變數;
i = i + 1
首先前面的'i='表明了i是一個局部變數(沒有global聲明, 創建局部變數), 然後後面的'i+1'里的i自然也是局部變數(同一個函數下同一個變數,i已經是局部變數了, 不能再當作全局變數去用), 那麼自然會報錯, i在使用前未聲明
i += 1
報錯就更明顯了, 沒有global聲明 那麼再修改變數i的時候, 自然是當作局部變數, 使用前未聲明
變數的查找順序遵循 LEGB 可以自己網路
關於作用域給你再寫個簡單的示例, 你對照著理解一下
Ⅳ python命名空間是什麼
在Python中,所有的名字都存在一個空間中,它們在該空間中存在和被操作——這就是命名空間。它就像一個盒子,每一個變數名字都對應裝著一個對象。當查詢變數的時候,會從該盒子裡面找到相應的對象。
【定義】
名稱到對象的映射。命名空間是一個字典的實現,鍵為變數名,值是變數對應的值。各個命名空間是獨立沒有關系的,一個命名空間中不能有重名,但是不同的命名空間可以重名而沒有任何影響。
相關推薦:《Python教程》
【分類】
python程序執行期間會有2個或3個活動的命名空間(函數調用時有3個,函數調用結束後2個)。按照變數定義的位置,可以劃分為以下3類:
Local,局部命名空間,每個函數所擁有的命名空間,記錄了函數中定義的所有變數,包括函數的入參、內部定義的局部變數。
Global,全局命名空間,每個模塊載入執行時創建的,記錄了模塊中定義的變數,包括模塊中定義的函數、類、其他導入的模塊、模塊級的變數與常量。
Built-in,python自帶的內建命名空間,任何模塊均可以訪問,放著內置的函數和異常。
【生命周期】
Local(局部命名空間)在函數被調用時才被創建,但函數返回結果或拋出異常時被刪除。(每一個遞歸函數都擁有自己的命名空間)。
Global(全局命名空間)在模塊被載入時創建,通常一直保留直到python解釋器退出。
Built-in(內建命名空間)在python解釋器啟動時創建,一直保留直到解釋器退出。
各命名空間創建順序:python解釋器啟動 ->創建內建命名空間 -> 載入模塊 -> 創建全局命名空間 ->函數被調用 ->創建局部命名空間
各命名空間銷毀順序:函數調用結束 -> 銷毀函數對應的局部命名空間 -> python虛擬機(解釋器)退出 ->銷毀全局命名空間 ->銷毀內建命名空間
python解釋器載入階段會創建出內建命名空間、模塊的全局命名空間,局部命名空間是在運行階段函數被調用時動態創建出來的,函數調用結束動態的銷毀的。
Ⅵ Python語言中命名空間的使用
如果一個命名聲明為全局的,那麼對它的所有引用和賦值會直接搜索包含這個模塊全局命名的作用域。如果要重新綁定最里層作用域之外的變數,可以使用 nonlocal 語句;如果不聲明為 nonlocal,這些變數將是只讀的(對這樣的變數賦值會在最裡面的作用域創建一個新的局部變數,外部具有相同命名的那個變數不會改變)。
通常,局部作用域引用當前函數的命名。在函數之外,局部作用域與全局使用域引用同一命名空間:模塊命名空間。類定義也是局部作用域中的另一個命名空間。
重要的是作用域決定於源程序的意義:一個定義於某模塊中的函數的全局作用域是該模塊的命名空間,而不是該函數的別名被定義或調用的位置,了解這一點非常重要。另一方面,命名的實際搜索過程是動態的,在運行時確定的——然而,Python 語言也在不斷發展,以後有可能會成為靜態的「編譯」時確定,所以不要依賴動態解析!(事實上,局部變數已經是靜態確定了。)
Python 的一個特別之處在於:如果沒有使用 global 語法,其賦值操作總是在最里層的作用域。賦值不會復制數據,只是將命名綁定到對象。刪除也是如此:del x 只是從局部作用域的命名空間中刪除命名 x 。事實上,所有引入新命名的操作都作用於局部作用域。特別是 import 語句和函數定義將模塊名或函數綁定於局部作用域(可以使用 global 語句將變數引入到全局作用域)。
global 語句用以指明某個特定的變數為全局作用域,並重新綁定它。nonlocal 語句用以指明某個特定的變數為封閉作用域,並重新綁定它。
Ⅶ python運行報錯 AttributeError: 'Namespace' object has no attribute 'image'
這要看你args是怎麼寫的。
如果你不理解什麼是args,就寫死路徑好了。
Ⅷ Python中的命名空間是什麼
編程語言中的命名空間簡單來說就是一些詞的集合,
同一個詞在不同的命名空間會有不同的意思,
用一個詞來做例子
「手紙」在中文這個命名空間是廁紙的意思,
而在日文這個命名空間是信的意思。
這個算是過分簡化的說明了。
Ⅸ Python lxml所有與多個命名空間問題,怎麼解決
有如下xml
<A xmlns="http://This/is/a/namespace">
<B>dataB1</B>
<B>dataB2</B>
<B>
<C>dataC</C>
</B>
</A>
其中的xmlns屬性表示的是該xml的默認命名空間,該命名空間必須是一個url形式
查看xml的tag
#encoding=utf8
from lxml import etree
str_xml = """
<A xmlns="http://This/is/a/namespace">
<B>dataB1</B>
<B>dataB2</B>
<B>
<C>dataC</C>
</B>
</A>
"""
xml = etree.fromstring(str_xml)
for node in xml.iter():
print node.tag
結果為:
{http://This/is/a/namespace}A
{http://This/is/a/namespace}B
{http://This/is/a/namespace}B
{http://This/is/a/namespace}B
{http://This/is/a/namespace}C
可以看到,跟普通xml的tag相比每個tag前面都多出了一個命名空間
獲取命名空間 .nsmap
from lxml import etree
str_xml = """
<A xmlns="http://This/is/a/namespace">
<B>dataB1</B>
<B>dataB2</B>
<B>
<C>dataC</C>
</B>
</A>
"""
xml = etree.fromstring(str_xml)
ns = xml.nsmap
print ns
print ns[None]
結果
{None: 'http://This/is/a/namespace'}
http://This/is/a/namespace
ns[None]獲取的是默認命名空間,ns會顯示所有的命名空間
獲取有命名空間的節點內容
from lxml import etree
str_xml = """
<A xmlns="http://This/is/a/namespace">
<B>dataB1</B>
<B>dataB2</B>
<B>
<C>dataC</C>
</B>
</A>
"""
xml = etree.fromstring(str_xml)
ns = xml.nsmap[None]
ns = "{%s}" % ns
for item in xml.findall("{0}B/{0}C".format(ns)): #不能用xpath會出錯
print item.text
結果
dataC
注意,在查找節點時,每一級節點都需要加上命名空間。而且測試時發現,findall可以正常查找到信息,而xpath會報錯。
獲取帶命名空間節點的屬性值
from lxml import etree
str_xml = """
<A xmlns="http://This/is/a/namespace">
<B b="123">dataB1</B>
<B>dataB2</B>
<B>
<C>dataC</C>
</B>
</A>
"""
xml = etree.fromstring(str_xml)
ns = xml.nsmap[None]
ns = "{%s}" % ns
item = xml.find(ns+"B")
print item.get("b")
print item.text
結果
123
dataB1
可以看到,獲取屬性時,不需要加命名空間,直接獲取即可