Python - 模組



Python 模組

Python 中的模組概念進一步增強了模組化。您可以將多個相關的函式定義在一起並載入所需的函式。模組是一個包含函式、變數、常量或任何其他 Python 物件定義的檔案。此檔案的內容可以提供給任何其他程式。Python 使用import關鍵字來實現此目的。

函式是一塊組織良好的、可重用的程式碼塊,用於執行單個相關的操作。函式為您的應用程式提供了更好的模組化和高度的程式碼重用。

Python 模組示例

import math
print ("Square root of 100:", math.sqrt(100))

這將產生以下輸出

Square root of 100: 10.0

Python 內建模組

Python 的標準庫包含大量模組。它們被稱為內建模組。大多數這些內建模組是用 C 編寫的(因為 Python 的參考實現是用 C 編寫的),並預編譯到庫中。這些模組打包了有用的功能,例如特定於系統的作業系統管理、磁碟 IO、網路等。

這是一個精選的內建模組列表:

序號 名稱和簡要說明

1

os

此模組為許多作業系統函式提供統一的介面。

2

string

此模組包含許多用於字串處理的函式。

3

re

此模組提供了一套強大的正則表示式功能。正則表示式 (RegEx) 允許對字串中的模式進行強大的字串搜尋和匹配。

4

math

此模組實現了許多浮點數的數學運算。這些函式通常是平臺 C 庫函式的薄包裝器。

5

cmath

此模組包含許多複數的數學運算。

6

datetime

此模組提供處理日期和一天中的時間的函式。它包裝了 C 執行時庫。

7

gc

此模組提供與內建垃圾收集器的介面。

8

asyncio

此模組定義了非同步處理所需的功能。

9

Collections

此模組提供高階容器資料型別。

10

functools

此模組具有高階函式和對可呼叫物件的運算。在函數語言程式設計中很有用。

11

operator

與標準運算子對應的函式。

12

pickle

將 Python 物件轉換為位元組流並返回。

13

socket

低階網路介面。

14

sqlite3

使用 SQLite 3.x 的 DB-API 2.0 實現。

15

statistics

數學統計函式

16

typing

對型別提示的支援

17

venv

建立虛擬環境。

18

json

編碼和解碼 JSON 格式。

19

wsgiref

WSGI 實用程式和參考實現。

20

unittest

Python 的單元測試框架。

21

random

生成偽隨機數。

22

sys

提供與直譯器強烈互動的函式。

23

requests

它透過提供一個使用者友好的介面來發送和處理響應來簡化 HTTP 請求。

Python 使用者自定義模組

任何帶有.py副檔名幷包含 Python 程式碼的文字檔案基本上都是一個模組。它可以包含一個或多個函式、變數、常量以及類的定義。可以透過 import 語句將模組中的任何 Python 物件提供給直譯器會話或另一個 Python 指令碼。模組還可以包含可執行的程式碼。

建立 Python 模組

建立模組只不過是用任何編輯器儲存 Python 程式碼。讓我們將以下程式碼儲存為mymodule.py

def SayHello(name):
   print ("Hi {}! How are you?".format(name))
   return

您現在可以在當前 Python 終端匯入 mymodule。

>>> import mymodule
>>> mymodule.SayHello("Harish")
Hi Harish! How are you?

您還可以在另一個 Python 指令碼中匯入一個模組。將以下程式碼儲存為 example.py

import mymodule
mymodule.SayHello("Harish")

從命令終端執行此指令碼

Hi Harish! How are you?

import 語句

在Python中,import關鍵字用於從一個模組載入Python物件。該物件可以是函式、類、變數等。如果一個模組包含多個定義,則所有定義都將載入到名稱空間中。

讓我們將以下包含三個函式的程式碼儲存為mymodule.py

def sum(x,y):
   return x+y

def average(x,y):
   return (x+y)/2

def power(x,y):
   return x**y

import mymodule語句將該模組中的所有函式載入到當前名稱空間中。匯入模組中的每個函式都是該模組物件的屬性。

>>> dir(mymodule)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'average', 'power', 'sum']

要呼叫任何函式,請使用模組物件的引用。例如,mymodule.sum()。

import mymodule
print ("sum:",mymodule.sum(10,20))
print ("average:",mymodule.average(10,20))
print ("power:",mymodule.power(10, 2))

這將產生以下輸出

sum:30
average:15.0
power:100

from ... import 語句

import語句將載入模組中的所有資源到當前名稱空間中。可以使用此語法從模組匯入特定物件。例如:

mymodule中的三個函式中,只有兩個在以下可執行指令碼example.py中匯入。

from mymodule import sum, average
print ("sum:",sum(10,20))
print ("average:",average(10,20))

它將產生以下輸出:

sum: 30
average: 15.0

請注意,不需要在函式名前新增模組名稱來呼叫函式。

from...import * 語句

也可以使用以下import語句將模組中的所有名稱匯入到當前名稱空間中:

from modname import *

這提供了一種簡單的方法將模組中的所有項匯入到當前名稱空間中;但是,應謹慎使用此語句。

import ... as 語句

您可以為匯入的模組分配一個別名。

from modulename as alias

呼叫函式時,應在函式名前新增別名

請看下面的例子

import mymodule as x
print ("sum:",x.sum(10,20))
print ("average:", x.average(10,20))
print ("power:", x.power(10, 2))

模組定位

匯入模組時,Python直譯器按以下順序搜尋模組:

  • 當前目錄。

  • 如果找不到模組,Python將搜尋shell變數PYTHONPATH中的每個目錄。

  • 如果所有方法都失敗,Python將檢查預設路徑。在UNIX系統上,此預設路徑通常為/usr/local/lib/python/。

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

PYTHONPATH 變數

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

這是一個來自Windows系統的典型PYTHONPATH:

set PYTHONPATH = c:\python20\lib;

這是一個來自UNIX系統的典型PYTHONPATH:

set PYTHONPATH = /usr/local/lib/python

名稱空間和作用域

變數是對映到物件的名稱(識別符號)。名稱空間是變數名(鍵)及其對應的物件(值)的字典。

  • Python語句可以訪問區域性名稱空間全域性名稱空間中的變數。如果區域性變數和全域性變數具有相同的名稱,則區域性變數將隱藏全域性變數。

  • 每個函式都有其自己的區域性名稱空間。類方法遵循與普通函式相同的作用域規則。

  • Python會根據情況猜測變數是區域性變數還是全域性變數。它假設在函式中賦值的任何變數都是區域性變數。

  • 為了在函式內為全域性變數賦值,必須首先使用global語句。

  • 語句global VarName告訴Python VarName是一個全域性變數。Python將停止搜尋區域性名稱空間中的變數。

示例

例如,我們在全域性名稱空間中定義了一個變數Money。在函式Money中,我們為Money賦值,因此Python將其視為區域性變數。但是,我們在設定區域性變數Money的值之前訪問了它的值,因此導致了UnboundLocalError錯誤。取消global語句的註釋可以解決此問題。

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

print (Money)
AddMoney()
print (Money)

模組屬性

在Python中,模組是module類的物件,因此它具有屬性。

以下是模組屬性:

  • __file__ 返回模組的物理名稱。

  • __package__ 返回模組所屬的包。

  • __doc__ 返回模組頂部的文件字串(如果存在)。

  • __dict__ 返回模組的整個作用域。

  • __name__ 返回模組的名稱。

示例

假設以下程式碼儲存為mymodule.py

"The docstring of mymodule"
def sum(x,y):
   return x+y

def average(x,y):
   return (x+y)/2
   
def power(x,y):
   return x**y

讓我們透過在以下指令碼中匯入它來檢查mymodule的屬性:

import mymodule

print ("__file__ attribute:", mymodule.__file__)
print ("__doc__ attribute:", mymodule.__doc__)
print ("__name__ attribute:", mymodule.__name__)

這將產生以下輸出

__file__ attribute: C:\math\examples\mymodule.py
__doc__ attribute: The docstring of mymodule
__name__ attribute: mymodule

__name__ 屬性

Python模組的__name__屬性具有重要意義。讓我們更詳細地探討它。

在互動式shell中,__name__屬性返回'__main__'。

>>> __name__
'__main__'

如果在直譯器會話中匯入任何模組,它將返回該模組的名稱作為該模組的__name__屬性。

>>> import math
>>> math.__name__
'math'

從Python指令碼內部,__name__屬性返回'__main__'。

#example.py
print ("__name__ attribute within a script:", __name__)

在命令終端執行此命令:

__name__ attribute within a script: __main__

此屬性允許Python指令碼用作可執行檔案或模組。與C++、Java、C#等不同,在Python中,沒有main()函式的概念。具有.py副檔名的Python程式指令碼可以包含函式定義和可執行語句。

儲存mymodule.py,程式碼如下:

"The docstring of mymodule"
def sum(x,y):
   return x+y
   
print ("sum:",sum(10,20))

您可以看到sum()函式是在定義它的同一個指令碼中呼叫的。

sum: 30

現在讓我們在另一個指令碼example.py中匯入此函式。

import mymodule
print ("sum:",mymodule.sum(10,20))

這將產生以下輸出

sum: 30
sum: 30

輸出“sum:30”出現了兩次。一次是在匯入mymodule模組時。匯入模組中的可執行語句也會執行。第二次輸出來自呼叫指令碼,即example.py程式。

我們想要的結果是,當匯入模組時,只匯入函式,而不執行其可執行語句。這可以透過檢查__name__的值來實現。如果它是__main__,則表示它正在執行而不是被匯入。有條件地包含可執行語句,例如函式呼叫。

mymodule.py中新增if語句,如下所示:

"The docstring of mymodule"
def sum(x,y):
   return x+y

if __name__ == "__main__":
   print ("sum:",sum(10,20))

現在,如果執行example.py程式,您會發現sum:30輸出只出現一次。

sum: 30

dir( ) 函式

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

該列表包含在模組中定義的所有模組、變數和函式的名稱。以下是一個簡單的示例:

# 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']

reload() 函式

有時您可能需要重新載入模組,尤其是在使用Python的互動式直譯器會話時。

假設我們有一個test模組(test.py),其中包含以下函式:

def SayHello(name):
   print ("Hi {}! How are you?".format(name))
   return

我們可以從Python提示符匯入模組並呼叫其函式,如下所示:

>>> import test
>>> test.SayHello("Deepak")
Hi Deepak! How are you?

但是,假設您需要修改SayHello()函式,例如:

def SayHello(name, course):
   print ("Hi {}! How are you?".format(name))
   print ("Welcome to {} Tutorial by TutorialsPoint".format(course))
   return

即使您編輯test.py檔案並儲存它,記憶體中載入的函式也不會更新。您需要使用imp模組中的reload()函式重新載入它。

>>> import imp
>>> imp.reload(test)
>>> test.SayHello("Deepak", "Python")
Hi Deepak! How are you?
Welcome to Python Tutorial by TutorialsPoint

Python中的包

包是一個分層檔案目錄結構,它定義了一個由模組、子包和子子包等組成的單個Python應用程式環境。

考慮一下Phone目錄中可用的檔案Pots.py。此檔案包含以下原始碼行:

def Pots():
   print "I'm Pots Phone"

同樣,我們還有另外兩個檔案,它們具有與上述相同的函式名稱:

  • Phone/Isdn.py檔案包含函式Isdn()

  • Phone/G3.py檔案包含函式G3()

現在,在Phone目錄中建立另一個檔案__init__.py:

  • Phone/__init__.py

為了在匯入Phone時使所有函式都可用,您需要在__init__.py中新增顯式匯入語句,如下所示:

from Pots import Pots
from Isdn import Isdn
from G3 import G3

在__init__.py中新增這些行後,匯入Phone包時,所有這些類都可用。

# 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類,然後您可以根據這些類建立包。

廣告