Python3模組


模組可以讓你從邏輯上組織你的Python程式碼。 將相關的程式碼放到一個模組使程式碼更容易理解和使用。 模組是可以繫結和參考任意命名的Python物件屬性。

簡單地說,一個模組是 Python 程式碼的檔案。 一個模組可以定義函式,類和變數。一個模組也可以包括可執行的程式碼。

範例

例如:一個名為 aname 模組的 Python程式碼通常放在一個指定為 aname.py 的檔案中。這裡有一個簡單的模組,support.py 的例子

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

import 語句

您可以通過在其他一些Python原始檔執行一個import語句,來使用任何Python原始檔作為一個模組。import 語句的語法如下:

import module1[, module2[,... moduleN] 

當解釋程式遇到import語句,如果模組存在於搜尋路徑它將匯入這個模組。搜尋路徑是一個目錄列表,直譯器匯入模組之前將進行搜尋。例如,要匯入模組 hello.py,需要在指令碼的頂部放置下面的命令 -

#!/usr/bin/python3

# Import module support
import support

# Now you can call defined function that module as follows
support.print_func("Zara")
當執行上面的程式碼,它產生以下結果 -
Hello : Zara 

模組被載入一次,不管它是匯入(import)的次數。如果多個匯入出現,這可以防止模組執行一遍又一遍。

from...import 語句

從Python的宣告語句,您可以從一個模組中匯入特定的屬性到當前的名稱空間。from...import 的語法如下-

from modname import name1[, name2[, ... nameN]]
例如,從 fib 模組匯入 fibonacci 函式,使用下面的語句-
#!/usr/bin/python3

# Fibonacci numbers module

def fib(n): # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result
>>> from fib import fib
>>> fib(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] 

此語句不匯入整個 fib 模組到當前的名稱空間; 它只是從 fib 模組匯入全域性符號表中的專案fibonacci。

from...import * 語句:

也可以使用下面的 import 語句, 將一個模組的所有名稱匯入到當前的名稱空間 -
from modname import * 

這提供了一種簡單的方法來匯入模組到當前名稱空間中的所有專案; 不過,這一說法應該盡量少用。

執行模組作為指令碼

在一個模組,模組名(做為一個字串)可以作為全域性變數__name__的值。該模組中的程式碼會被執行,就好像匯入它一樣,但設定為「__main__」的 __name__。這意味著,通過在模組的末尾新增以下程式碼:

#!/usr/bin/python3

# Fibonacci numbers module

def fib(n): # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result
if __name__ == "__main__":
    f=fib(100)
    print(f)
當我們執行上面的程式碼,以下輸出將顯示
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

查詢模組

當匯入模組,在下面 Python直譯器將搜尋模組的序列 -
  • 當前目錄。
  • 如果沒有找到該模組,然後 Python 將搜尋 shell 變數 PYTHONPATH 的每個目錄.

  • 如果這些方法都失敗(未找到),Python檢查預設路徑。 在UNIX上,預設路徑通常是 /usr/local/lib/python3/.

模組搜尋路徑被儲存在系統模組sys作為所述的 sys.path 變數。sys.path中變數包含當前目錄,PYTHONPATH和安裝相關的預設目錄。

PYTHONPATH 變數:

PYTHONPATH 是一個環境變數,它由一個目錄列表組成。Python路徑中的語法與 shell 變數PATH相同。

下面是 Windows系統中一個典型的 PYTHONPATH :
set PYTHONPATH=c:\python34\lib;
這裡是 UNIX 系統的典型 PYTHONPATH :
set PYTHONPATH=/usr/local/lib/python

名稱空間和範圍界定

變數名稱(標識)對映到物件。名稱空間是一組變數(鍵)及其相應的物件(值)的字典。

使用Python編寫的語句可以在本地名稱空間和全域性名稱空間存取變數。如果本地和全域性變數具有相同的名稱,區域性變數將覆蓋全域性變數。

每個函式都有它自己的本地名稱空間。 類方法與普通的函式遵循相同的範圍規則。

Python作出明智的猜測變數是區域性還是全域性的。它假定任何變數賦值在函式中的值是區域性的。

因此,為了給一個函式內給一個全域性變數賦值, 您必須使用global語句。

宣告全域性 VarName 告訴 Python 的 VarName 是一個全域性變數。Python停止在區域性名稱空間搜尋該變數。

例如,我們在全域性名稱空間定義一個變數Money。在函式變數 Money,我們給的 Money 的值,因此 Python 假定 Money 作為一個區域性變數。 然而,我們將其設定之前計算區域性變數 Money 的值, 所以一個 UnboundLocalError 錯誤被引發。取消全域性宣告解決了這個問題。

#!/usr/bin/python3

Money = 2000
def AddMoney():
   # Uncomment the following line to fix the code:
   # global Money
   Money = Money + 1

print (Money)
AddMoney()
print (Money)

dir( ) 函式

使用 dir()內建函式返回一個包含由模組定義的名稱字串的排序列表。

該列表包含一個模組中定義的所有的模組,變數和函式的名稱。下面是一個簡單的例子 -

#!/usr/bin/python3

# Import built-in module math
import math

content = dir(math)

print (content)
當執行上面的程式碼,它產生以下結果 -
['__doc__', '__file__', '__name__', 'acos', 'asin', 'atan', 
'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 
'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log',
'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 
'sqrt', 'tan', 'tanh'] 

在這裡,特殊字串變數__name__是模組的名稱,__file__是載入模組的檔案名。

globals() 和 locals() 函式?

globals() 和 locals()函式可用於在全域性和區域性命名空間返回名稱,取決於從哪裡呼叫它們。

如果 locals() 從函式中呼叫, 它會返回所有可以從函式存取的名字。

如果 globals() 可以在一個函式中呼叫,它將返回所有可以在全域性範圍內,可從函式存取的名字。

兩種這些函式的返回型別是字典。因此,名稱可以使用 keys() 函式來提取。

reload() 函式

當模組被匯入到一個指令碼,在模組的頂層部的程式碼只執行一次。

因此,如果你希望模組重新執行的頂層程式碼, 可以使用 reload()函式。在reload()函式會再次匯入先前匯入模組。reload()函式的語法是這樣的 -

reload(module_name) 

在這裡,module_name 是要重新載入模組,而不是包含模組名稱的字串。例如,要重新載入模組 hello,請執行下列操作 ?

reload(hello)

Python包

包是一個分層檔案目錄結構,定義由模組和子包和子子包等一個單一的Python應用環境。
考慮在 Phone 目錄下找到的檔案Pots.py。此檔案的原始碼如下面的行 -
#!/usr/bin/python3

def Pots():
   print ("I'm Pots Phone")  
類似的方式,這裡有不同功能的兩個相同名稱檔案如下 -
  • Phone/Isdn.py有一個函式 Isdn()

  • Phone/G3.py 有一個函式 G3()

現在,在 Phone 目錄中建立一個檔案__init__.py-
  • Phone/__init__.py

為了讓所有的功能可用,當匯入Phone,需要把明確 import 語句在 __init__.py 中如下 -

from Pots import Pots
from Isdn import Isdn
from G3 import G3
在新增這些行到 __init__.py 後,當匯入 Phone 包所有的這些類可用。
#!/usr/bin/python3

# Now import your Phone Package.
import Phone

Phone.Pots()
Phone.Isdn()
Phone.G3()
當執行上面的程式碼,它產生以下結果 -
I'm Pots Phone
I'm 3G Phone
I'm ISDN Phone 

在上面的例子中,我們已經在每個檔案採取一個單一的函式範例,但可以保留多個函式在檔案中。您還可以定義這些Python類不同的檔案中,然後你可以建立包在那些類之外。