python包的導入
『壹』 python包相對導入的陷阱是
包相對導入的陷阱:混合使用,相比於Python 2.X的隱式包相對導入,以及Python 2.X和3.X中的顯式包相對導入點號語法,有些時候從 sys.path上一個路徑出發的絕對包導入會是更推薦的選擇。這一問題可能看上去難以理解,但是當你開始編寫自己的包,可能就會變得更加重要了。 如前所述,Python 3.X的相對導入語法和默認絕對導入搜索規則,讓包內導入變得顯式從而使其更容易被注意和被維護,而且允許你在一些命名沖突的情況下顯式地進行選擇。然而,你也必須注意到該模型帶來的下面兩個結果:在Python 3.X和2.X中,包相對導入語句的使用會隱式地將一個文件與一個包目錄的角色進行綁定,並禁止該文件通過其他方式被使用。在Python 3.X中,新的相對導入搜索規則改變意味著一個文件不能像在2.X中那樣同時扮演腳本和包模塊的角色。這些約束的理由有些微妙,不過由於下面的兩條同時成立:Python 3.X和2.X不允許隨意使用from .的相對導入語法,除非發起導入的文件本身作為包的一部分(即該文件在其他地方被導入)。Python 3.X的導入不會搜索一個包模塊自身的路徑,除非使用了from .的相對導入語法(或該模塊位於當前工作路徑、頂層腳本的主目錄下)。使用相對導入會阻止你在2.X和3.X中創建同時扮演可執行程序和外部可導入包角色的目錄項。此外,一些文件在3.X中不能像在2.X中那樣同時扮演腳本和包模塊的角色。就導人語句來說,這些規則可以歸結為下面的兩行代碼的形式:前一行在Python 2.X和3.X中都只用於包模式,而後一行在3.X中只用於程序模式。
最終的效果是不論2.X還是3.X中的文件,你都應該只選擇一種使用模式,即包模式(使用相對導入)或程序模式(使用簡單導入),並將真正的包模塊文件單獨放到一個子目錄中,與頂層腳本文件隔離開來。
另一方面,你可以嘗試手動改變sys.path(通常是一項脆弱並易出錯的任務)或總是通過絕對導入使用完整的包路徑,並且假定包的根目錄位於模塊搜索路徑上,來替代包相對導入語法或簡單導入。
『貳』 python2包的導入問題
可以試試在core和config文件夾的同級再加上__init__.py(為了表名這文件夾也是一個模塊)
『叄』 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怎麼導入文件
Python的import包含文件功能就跟PHP的include類似,但更確切的說應該更像是PHP中的require,因為Python里的import只要目標不存在就報錯程序無法往下執行。要包含目錄里的文件,PHP中只需要給對路徑就OK。Python中則不同,下面來看看這個例子。
目錄結構:
重新執行a.py,一切OK!
『伍』 python怎樣導入自己寫的包
python導入自己寫的包的方法:
1、導入同級目錄下的文件可以用「import 包名」導入
2、導入子目錄文件可以用「from 包名 import 文件名」導入
更多Python知識,請關註:Python自學網!!
『陸』 如何把一個python包導入到python庫中
Python 運行環境在查找模塊時是對 sys.path 列表進行遍歷,如果我們想在運行環境中添加自定義的模塊,主要有以下三種方法:
1. 在sys.path列表中添加新的路徑(只能對執行了 sys.path.append 命令的當前 Python 運行環境起作用,對其他運行環境不起作用,也即「一次性」的)。
>>> import sys
>>> sys.path
>>> sys.path.append('/home/xxx/yyy') #目錄/home/xxx/yyy包含你所需要的包或模塊
設置 PYTHONPATH 環境變數(永久性添加):
2. 將包或模塊復制到 sys.path 列表中的目錄(通過 sys.path 查看)里(如 /home/test/lib/python2.7/site-packages/ 目錄)。
3. 最簡單的辦法是用 .pth 文件來實現。Python 在遍歷已有的庫文件目錄(sys.path中指定)過程中,如果見到一個 .pth 文件,就會將該文件中所記錄的路徑加入到 sys.path 設置中,這樣 .pth 文件說指明的庫也就可以被 Python 運行環境找到。
$cd /home/test/lib/python2.7/site-packages/
$touch test.pth
$vim test.pth
$添加一行包或模塊所在的目錄(如:/home/test/somePackage/)
則test.pth文件內容為:
/home/test/somePackage/
『柒』 python怎麼導入自己寫的包
包(packages)其實也是模塊,其類型Type也是mole。通常引用自定義模塊時有兩種方法:
1)將兩個文件放在同一目錄下。
2)在sys.path下添加要引用的py文件的路徑。然後import。
這樣的做法,對於少數文件是可行的,但如果程序數目很多,層級很復雜時就比較麻煩了。此時用package就能將多個py文件組織起來,類似於第三方包一樣的引用。要方便很多。
package的層次結構與程序所在目錄的層次結構相同,且必須包含一個__init__.py的文件。__init__.py可以為空,只要它存在就表明此目錄被作為一個package處理。
package1/
__init__.py
subPack1/
__init__.py
mole_11.py
mole_12.py
mole_13.py
subPack2/
__init__.py
mole_21.py
mole_22.py
……
__init__.py可以為空,只要它存在,就表明此目錄應被作為一個package處理。當然,__init__.py中也可以設置相應的內容。
好了,現在我們在mole_11.py中定義一個函數:
def funA():
print "funcA in mole_11"
return
一.引用模塊
在頂層目錄(也就是package1所在的目錄,當然也參考上面的介紹,將package1放在解釋器能夠搜索到的地方)運行python:
>>>from package1.subPack1.mole_11 import funcA
>>>funcA()
funcA in mole_11
這樣,我們就按照package的層次關系,正確調用了mole_11中的函數。
二.使用通配符*,導入某個mole中的所有元素
答案就在__init__.py中。我們在subPack1的__init__.py文件中寫
__all__ = ['mole_13', 'mole_12']
然後進入python
>>>from package1.subPack1 import *
>>>mole_11.funcA()
Traceback (most recent call last):
File "", line 1, in
ImportError: No mole named mole_11
也就是說,以*導入時,package內的mole是受__init__.py限制的。
三.在package內部互相調用。
1.如果希望調用同一個package中的mole,則直接import即可。也就是說,在mole_12.py中,可以直接使用
import mole_11
2.如果不在同一個package中,例如我們希望在mole_21.py中調用mole_11.py中的FuncA,則應該這樣:
from mole_11包名.mole_11 import funcA
四.Python如何找到我們定義的mole?
在標准包sys中path屬性記錄了Python的包路徑。
import sys
print(sys.path)
通常我們可以將mole的包路徑放到環境變數PYTHONPATH中,該環境變數會自動添加到sys.path屬性.
另一種方便的方法是編程中直接指定我們的mole路徑到sys.path 中。
常用的話也可以放在python27\lib\site-packages文件夾下。
『捌』 python 中庫怎麼導入
讓包內導入更加顯式,這個功能的一部分設計初衷是,為了幫助腳本解決同名文件出現在模塊搜索路徑上多個不同位置時的二義性。考慮包目錄,這定義了一個名為mypkg 的包,其中含有名為mypkg.main和mypkg.string 的模塊。現在,假設模塊main試圖導入名為string的模塊。在 Python 2.X和更早版本中,Python會先尋找mypkg目錄以執行相對導入。這會找到並導入位於該處的string.py文件,將其賦值給mypkg.main模塊命名空間內的名稱string。不過,這一導入的本意可能是要導入Python標准庫的string模塊。可惜的是,在這些Python版本中,無法直接忽略mypkg.string 去尋找位於模塊搜索路徑更右側的標准庫中的string模塊。此外,我們無法使用完整包導入路徑來解決這個問題,因為我們無法依賴在每台機器上的標准鏈接庫路徑。換句話說,包中的簡單導入可能具有二義性而且容易出錯。在包內,我們無法確定imports pam語句指的是包內的模塊還是包外的模塊。一種可能的後果是,一個局部的模塊或包會在不經意間隱藏了sys.path 上的另一個模塊。
在實踐中,Python使用者可以避免為他們自己的模塊重復使用標准庫模塊的名稱(如果需要標准string庫,就不要把新的模塊命名為string)。但是,一個包還是有可能意外地隱藏標准庫模塊。再者,Python 以後可能新增標准庫模塊,而其名稱可能剛好就和自己的一個模塊同名。而依賴於沒有點號開頭相對導入的程序代碼同樣也不容易理解,因為讀者可能對希望使用哪個模塊而感到困惑。所以我們最好能在代碼中顯式地指出導入的解析過程。
『玖』 如何導入python中的模塊
定義模塊,只要使用文本編輯器,把一些python代碼輸入到文本中,然後以.py為後綴名進行保存,任何此類文件都會被認為是python模塊。
比如說,下面的代碼輸入到一個文件中,就可以看作是一個模塊:
def
printme(var):
print
varif
__name__
==
'__main__':
printme(1)
假設說輸入到a.py中,那麼import
a就可以把這個模塊導入。
然後可執行a.printme(3),屏幕即可列印出3:
>>>
a.printme(3)3>>>
一個模塊頂層定義的變數,會自動變成模塊的屬性。例如:
data=[1,2,3]def
printme(var):
print
varif
__name__
==
'__main__':
printme(1)
data變數就是模塊的一個屬性。其實printme也是一個屬性,只不過是一個函數罷了。
引入模塊示例如下:(假定此時data=[1,2,3]未定義)
>>>
import
a>>>
a.data
Traceback
(most
recent
call
last):
File
"<pyshell#1>",
line
1,
in
<mole>
a.dataAttributeError:
'mole'
object
has
no
attribute
'data'>>>
reload(a)<mole
'a'
from
'C:/py\a.pyc'>>>>
a.data
Traceback
(most
recent
call
last):
File
"<pyshell#3>",
line
1,
in
<mole>
a.dataAttributeError:
'mole'
object
has
no
attribute
'data'>>>
從上述提示可以看出data屬性未定義,此時再在a.py文件中定義data=[1,2,3],重新載入a模塊,並輸出data屬性:
>>>
reload(a)<mole
'a'
from
'C:/py\a.py'>>>>
a.data[1,
2,
3]>>>
這里的reload函數可以重新載入一個模塊。如果在模塊代碼中更改了,那麼需要重新載入。
上面a.data,就是訪問模塊中的屬性。
上面的例子是導入一個文件作為一個模塊。
其實python的模塊導入還有更豐富的內容。
除了模塊名之外,python也可以導入指定目錄路徑。python代碼的目錄就稱為包。因此,這類導入就稱為包導入。事實上,包導入是把計算機上的目錄變成python的一個命名空間。而屬性就是目錄中包含的子目錄或者是模塊文件。
看下面例子:
在我的桌面上有一個aa文件夾,裡面有bb文件夾,bb裡面有a.py這個文件。
那麼在aa和bb文件夾中分別放置一個__init__.py,之後,在命令行中import
aa.bb.a,就可以導入模塊a了。
『拾』 python 類和繼承,包及模塊導入 求解答
一 .mole
通常模塊為一個文件,直接使用import來導入就好了。可以作為mole的文件類型有".py"、".pyo"、".pyc"、".pyd"、".so"、".dll"。
二. package
通常包總是一個目錄,可以使用import導入包,或者from + import來導入包中的部分模塊。包目錄下為首的一個文件便是 __init__.py。然後是一些模塊文件和子目錄,假如子目錄中也有 __init__.py 那麼它就是這個包的子包了。
一.模塊你可以使用import語句將一個源代碼文件作為模塊導入.例如:
[python]view plain
#file:spam.py
a=37#一個變數
deffoo:#一個函數
print"I'mfoo"
classbar:#一個類
defgrok(self):
print"I'mbar.grok"
b=bar()#創建一個實例
- 1.為源代碼文件中定義的對象創建一個名字空間,通過這個名字空間可以訪問到模塊中定義的函數及變數。
- 2.在新創建的名字空間里執行源代碼文件.
- 3.創建一個名為源代碼文件的對象,該對象引用模塊的名字空間,這樣就可以通過這個對象訪問模塊中的函數及變數,如:
importspam#導入並運行模塊spam
printspam.a#訪問模塊spam的屬性
spam.foo()
c=spam.bar()
importsocket,os,regex
- 模塊導入時可以使用 as 關鍵字來改變模塊的引用對象名字:
importosassystem
importsocketasnet,threadasthreads
system.chdir("..")
net.gethostname()
- 使用from語句可以將模塊中的對象直接導入到當前的名字空間. from語句不創建一個到模塊名字空間的引用對象,而是把被導入模塊的一個或多個對象直接放入當前的名字空間:
fromsocketimportgethostname#將gethostname放如當前名字空間
printgethostname()#直接調用
socket.gethostname()#引發異常NameError:socket
fromsocketimportgethostname,socket
fromsocketimport*#載入所有對象到當前名字空間
- 不過,如果一個模塊如果定義有列表__all__,則from mole import * 語句只能導入__all__列表中存在的對象。
#mole:foo.py
__all__=['bar','spam']#定義使用`*`可以導入的對象
h=hostname()
- from mole import * 語句只能用於一個模塊的最頂層.*特別注意*:由於存在作用域沖突,不允許在函數中使用from 語句。
- 每個模塊都擁有 __name__ 屬性,它是一個內容為模塊名字的字元串。最頂層的模塊名稱是 __main__ .命令行或是交互模式下程序都運行在__main__ 模塊內部. 利用__name__屬性,我們可以讓同一個程序在不同的場合(單獨執行或被導入)具有不同的行為,象下面這樣做:
#檢查是單獨執行還是被導入
if__name__=='__main__':
#Yes
statements
else:
#No(可能被作為模塊導入)
statements
- 模塊搜索路徑
- 導入模塊時,解釋器會搜索sys.path列表,這個列表中保存著一系列目錄。一個典型的sys.path 列表的值:
- Linux:
- ['', '/usr/local/lib/python2.0',
- '/usr/local/lib/python2.0/plat-sunos5',
- '/usr/local/lib/python2.0/lib-tk',
- '/usr/local/lib/python2.0/lib-dynload',
- '/usr/local/lib/python2.0/site-packages']
- Windows:
- ['', 'C:\WINDOWS\system32\python24.zip', 'C:\Documents and Settings\weizhong', 'C:\Python24\DLLs', 'C:\Python24\lib', 'C:\Python24\lib\plat-win', 'C:\Python24\lib\lib-tk', 'C:\Python24\Lib\site-packages\pythonwin', 'C:\Python24', 'C:\Python24\lib\site-packages', 'C:\Python24\lib\site-packages\win32', 'C:\Python24\lib\site-packages\win32\lib', 'C:\Python24\lib\site-packages\wx-2.6-msw-unicode']
- 空字元串 代表當前目錄. 要加入新的搜索路徑,只需要將這個路徑加入到這個列表.
- 模塊導入和匯編
- 到現在為止,本章介紹的模塊都是包含Python源代碼的文本文件. 不過模塊不限於此,可以被 import 語句導入的模塊共有以下四類:
- •使用Python寫的程序( .py文件)
- •C或C++擴展(已編譯為共享庫或DLL文件)
- •包(包含多個模塊)
- •內建模塊(使用C編寫並已鏈接到Python解釋器內)
- 當查詢模塊 foo 時,解釋器按照 sys.path 列表中目錄順序來查找以下文件(目錄也是文件的一種):
- 1.定義為一個包的目錄 foo
- 2.foo.so, foomole.so, foomole.sl,或 foomole.dll (已編譯擴展)
- 3.foo.pyo (只在使用 -O 或 -OO 選項時)
- 4.foo.pyc
- 5.foo.py
- 對於.py文件,當一個模塊第一次被導入時,它就被匯編為位元組代碼,並將位元組碼寫入一個同名的 .pyc文件.後來的導入操作會直接讀取.pyc文件而不是.py文件.(除非.py文件的修改日期更新,這種情況會重新生成.pyc文件) 在解釋器使用 -O 選項時,擴展名為.pyo的同名文件被使用. pyo文件的內容雖去掉行號,斷言,及其他調試信息的位元組碼,體積更小,運行速度更快.如果使用-OO選項代替-O,則文檔字元串也會在創建.pyo文件時也被忽略.
- 如果在sys.path提供的所有路徑均查找失敗,解釋器會繼續在內建模塊中尋找,如果再次失敗,則引發 ImportError 異常.
- .pyc和.pyo文件的匯編,當且僅當import 語句執行時進行.
- 當 import 語句搜索文件時,文件名是大小寫敏感的。即使在文件系統大小寫不敏感的系統上也是如此(Windows等). 這樣, import foo 只會導入文件foo.py而不會是FOO.PY.
- 重新導入模塊
- 如果更新了一個已經用import語句導入的模塊,內建函數reload()可以重新導入並運行更新後的模塊代碼.它需要一個模塊對象做為參數.例如:
- import foo
- ... some code ...
- reload(foo) # 重新導入 foo
- 在reload()運行之後的針對模塊的操作都會使用新導入代碼,不過reload()並不會更新使用舊模塊創建的對象,因此有可能出現新舊版本對象共存的情況。 *注意* 使用C或C++編譯的模塊不能通過 reload() 函數來重新導入。記住一個原則,除非是在調試和開發過程中,否則不要使用reload()函數.
使用import spam 語句就可以將這個文件作為模塊導入。系統在導入模塊時,要做以下三件事:
[python]view plain
用逗號分割模塊名稱就可以同時導入多個模塊:
[python]view plain
[python]view plain
[python]view plain
from語句支持逗號分割的對象,也可以使用星號(*)代表模塊中除下劃線開頭的所有對象:
[python]view plain
[python]view plain
另外, as 也可以和 from 聯合使用:
[python]view plain
import 語句可以在程序的任何位置使用,你可以在程序中多次導入同一個模塊,但模塊中的代碼*僅僅*在該模塊被首次導入時執行。後面的import語句只是簡單的創建一個到模塊名字空間的引用而已。sys.moles字典中保存著所有被導入模塊的模塊名到模塊對象的映射。這個字典用來決定是否需要使用import語句來導入一個模塊的最新拷貝.
[python]view plain