Python模組

模組允許邏輯地組織Python代碼。 將相關代碼分組到一個模組中,使代碼更容易理解和使用。 模組是一個具有任意命名屬性的Python對象,可以綁定和引用。

簡單來說,模組是一個由Python代碼組成的檔。模組可以定義函數,類和變數。 模組還可以包括可運行的代碼。

示例

下麵是一個名稱為aname的模組的Python代碼通常位於一個名稱為aname.py的檔中。以下是一個簡單模組的例子:support.py -

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

1.import語句

可以通過在其他Python原始檔案中執行import語句來將任何Python原始檔案用作模組。導入具有以下語法 -

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

當解釋器遇到導入語句時,如果模組存在於搜索路徑中,則導入該模組。搜索路徑是導入模組之前解釋器搜索的目錄的列表。例如,要導入模組hello.py,需要將以下命令放在腳本的頂部 -

#!/usr/bin/python3

# Import module support
import support

# Now you can call defined function that module as follows
support.print_func("Maxsu")

當執行上述代碼時,會產生以下結果 -

Hello : Maxsu

不管模組被導入多少次,模組只能加載一次。這樣可以防止模組執行重複發生,如果有多個導入。

2.from…import語句

Python from語句允許將模組中的特定屬性導入到當前的命名空間中。 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導入到當前命名空間中; 它只是將fibonacci從模組fib引入導入模組的全局符號表。

3.from…import *語句

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

from modname import *

這提供了將所有專案從模組導入到當前命名空間中的簡單方法; 但是,這個說法應該謹慎使用。

4.執行模組作為腳本

在模組中,模組的名稱(作為字串)可用作全局變數__name__的值。模組中的代碼將被執行,就像您導入它一樣,但是__name__設置為“__main__”。

在模組的最後添加這個代碼 -

#!/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]

5.定位模組

當導入模組時,Python解釋器將按以下順序搜索模組 -

  • 當前目錄。
  • 如果沒有找到該模組,Python會在shell變數PYTHONPATH中搜索每個目錄。
  • 如果其他所有失敗,Python將檢查默認路徑。 在UNIX上,此默認路徑通常是/usr/local/lib/python3/ 或者 /usr/sbin/

模組搜索路徑作為sys.path變數存儲在系統模組sys中。sys.path變數包含當前目錄PYTHONPATH和依賴於安裝的默認值。

6.PYTHONPATH變數

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

這是一個典型的Windows系統上的PYTHONPATH -

set PYTHONPATH = c:\python34\lib;

這裏是UNIX系統的典型PYTHONPATH -

set PYTHONPATH = /usr/local/lib/python

7.命名空間和範圍

變數是映射到對象的名稱(識別字)。 命名空間是變數名(鍵)及其對應對象(值)的字典。

  • Python語句可以訪問本地命名空間和全局命名空間中的變數。如果本地和全局變數具有相同的名稱,則局部變數會影響全局變數。
  • 每個函數都有自己的本地命名空間。 類方法遵循與普通函數相同的範圍規則。
  • Python對於變數是本地還是全局都進行了有根據的判斷。它假定在函數中分配值的任何變數都是本地的。
  • 因此,為了將值分配給函數內的全局變數,必須首先使用global語句。
  • 語句global VarName告訴Python VarName是一個全局變數。Python停止搜索本地命名空間的變數。

例如,在全局命名空間中定義一個變數Money。 在函數Money中為Money賦值,因此Python將Money作為局部變數。

但是,如果在設置之前就訪問了本地變數Money的值,它會產生一個錯誤:UnboundLocalError。 這裏可以通過取消注釋global語句來解決問題。如下示例代碼 -

#!/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)

8.dir( )函數

dir()內置函數返回一個包含由模組定義的名稱的字串的排序列表。這個列表包含模組中定義的所有模組,變數和函數的名稱。 以下是一個簡單的例子 -

#!/usr/bin/python3

# Import built-in module math
import time

content = dir(time)

print (content)

當執行上述代碼時,會產生以下結果 -

['_STRUCT_TM_ITEMS', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'altzone', 'asctime', 'clock', 'ctime', 'daylight', 'get_clock_info', 'gmtime', 'localtime', 'mktime', 'monotonic', 'perf_counter', 'process_time', 'sleep', 'strftime', 'strptime', 'struct_time', 'time', 'timezone', 'tzname']

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

9.globals()和locals()函數

globals()locals()函數可用於返回全局和本地命名空間中的名稱,具體取決於它們被調用的位置。

  • 如果locals()從一個函數中調用,它將返回從該函數本地訪問的所有名稱。
  • 如果從函數中調用globals(),它將返回從該函數全局訪問的所有名稱。

這兩個函數的返回類型是字典。 因此,可以使用keys()函數提取名稱。

10.reload()函數

當將模組導入到腳本中時,模組的頂級部分的代碼只能執行一次。
因此,如果要重新執行模組中的頂級代碼,可以使用reload()函數。reload()函數再次導入以前導入的模組。 reload()函數的語法是這樣的 -

reload(module_name)

這裏,module_name是要重新加載的模組的名稱,而不是包含模組名稱的字串。 例如,要重新加載hello模組,請執行以下操作 -

reload(hello)

11.Python中的包

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

package目錄中創建兩個目錄:pkgpkg2, 然後分別在這兩個目錄中創建兩個檔:a.pyb.py。該檔具有以下一行源代碼 -

檔: pkg/a.py -

#!/usr/bin/python3
#coding=utf-8
# save file: pkg/a.py
def fun():
    print ("I'm pkg.a.fun() ")

檔: pkg/b.py -

#!/usr/bin/python3
#coding=utf-8
# save file: pkg/b.py
def fun():
    print ("I'm pkg.b.fun() ")

檔: pkg2/a.py -

#!/usr/bin/python3
#coding=utf-8
# save file: pkg2/a.py
def fun():
    print ("I'm pkg2.a.fun() ")

檔: pkg2/b.py -

#!/usr/bin/python3
#coding=utf-8
# save file: pkg2/b.py
def fun():
    print ("I'm pkg2.b.fun() ")

package目錄中創建一個主程序檔:main.py,用於演示如何調用包中的各個檔 -

#!/usr/bin/python3
#coding=utf-8
# save file: phone/pots.py

import pkg.a as a
import pkg.b as b

import pkg2.a as a2
import pkg2.b as b2

a.fun()
b.fun()

a2.fun()
b2.fun()

import pkg2.a
import pkg2.b

print('----------- another way -----------------')
pkg2.a.fun()
pkg2.b.fun()

整個代碼的目錄如下所示 -

package
  |- pkg
      |- __init__.py
      |- a.py
      |- b.py
  |- pkg2
      |- __init__.py
      |- a.py
      |- b.py

當執行上述代碼時,會產生以下結果 -

I'm pkg.a.fun()
I'm pkg.b.fun()
I'm pkg2.a.fun()
I'm pkg2.b.fun()
----------- another way -----------------
I'm pkg2.a.fun()
I'm pkg2.b.fun()

在上面的例子中,將每個檔中的一個函數作為示例,但是可以在檔中編寫多個函數。還可以在這些檔中定義不同的Python類,然後可以使用這些類來創建包。


上一篇: Python函數 下一篇: Python檔讀寫