自己手動寫了一些.py文件,在互相import的時候總是出錯。搞了一下午,終於解決了問題。要注意得是,必須要理清python中的幾個概念:模塊(Module)和包。


python基本概念

?python模塊

Python 模塊(Module),是一個 Python 文件,以 .py 結尾,包含了 Python 對象定義和Python語句。

模塊讓你能夠有邏輯地組織你的 Python 代碼段。

把相關的代碼分配到一個模塊里能讓你的代碼更好用,更易懂。

模塊能定義函數,類和變數(所以,一開始我認為的函數必須在類里是錯的...受java的毒了),模塊里也能包含可執行的代碼。

?python包

包是一個分層次的文件目錄結構,它定義了一個由模塊及子包,和子包下的子包等組成的 Python 的應用環境。

簡單來說,包就是文件夾,但該文件夾下必須存在 __init__.py 文件, 該文件的內容可以為空。__init__.py 用於標識當前文件夾是一個包。


場景應用

?導入同級目錄文件

如果需要引入同級目錄下的文件,則可以採用import一個模塊的形式,即可調用。

考慮同一目錄下的兩個python文件,test.py 需要調用support.py 中的函數,目錄結構如下:

|-- test.py
|-- support.py

support.py 中的代碼如下:

def print_func( par ):
print "Hello : ",
par return

test.py 調用的代碼如下:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 導入模塊
import support

# 現在可以調用模塊里包含的函數了
support.print_func("Runoob")

可以看到,上面的support.py 只有一個函數。假如這個函數在類中的話,即support.py 為:

class supportClass(object):
def print_func( par ):
print ("Hello : ", par)
return

那麼如果test.py 中的代碼不變,就會報錯:

AttributeError: module support has no attribute print_func

這是因為,雖然import進來了support這個模塊,但是print_func並不是直接在這個模塊中的,而是在類supportClass中。所以直接調用support.print_func("Runoob")就出錯了。

最顯然的解決方式為,在test.py 中這麼寫:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 導入模塊
import support #或者寫成from support import *

# 現在可以調用模塊里包含的函數了
support.supportClass.print_func("Runoob") #輸出:Hello : Runoob

題外話:無論是import XXX 還是 from XXX import AAA ,XXX都是模塊,AAA可以是這個模塊中的函數,類或者變數。

自己一開始犯的錯:不要把類的名字和module的名字設成一樣,否則,會報:

Python AttributeError: module object has no attribute xxxx

導致在這個問題的原因是模塊名和要引用的類或方法或變數的名字重了。說通俗點就是,python腳本名字(模塊名)和要引用的內容(模塊內的類,變數等)的名字重複了,導致原本「類->屬性/方法」的引用意圖被解析為了"模塊->屬性」的引用意圖。當模塊下面沒有這個屬性,就拋出了這個錯誤。解決辦法是換不重複的命名。

這與JAVA要求文件名和類名是一樣的要求是完全不同的。

?導入子目錄文件

如果需要引入子目錄下的文件,則可以採用import一個包的形式,將子目錄封裝成包,即可調用。

考慮一個在 package_runoob 目錄下的 runoob1.py、runoob2.py、__init__.py 文件,test.py 為測試調用包的代碼,目錄結構如下:

test.py
package_runoob
|-- __init__.py
|-- runoob1.py
|-- runoob2.py

__init__.py可以是空文件。

test.py 調用代碼如下:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 導入 Phone 包
from package_runoob.runoob1 import func1
from package_runoob.runoob2 import func2

func1()
func2()

也可以採用

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 導入 Phone 包
import package_runoob.runoob1
import package_runoob.runoob2

package_runoob.runoob1.func1()
package_runoob.runoob2.func2()

推薦閱讀:

相关文章