1. 程式人生 > Python進階應用教學 >15 Python 標準庫之 sys 模組

15 Python 標準庫之 sys 模組

上節課我們學習了 Python 中的 OS 標準庫 ,這節課我們來學習下另外一個 標準庫 sys。

1. sys.exit(code)

sys.exit(code) 的功能是退出程式:

  • 引數 code,退出程式碼,通常 0 代表正常退出,其它值程式碼異常退出
  • 返回值,無

演示 sys.exit(code) 的例子如下:

import sys

print('hello')
sys.exit(0)
print('world')
  • 在第 3 行,列印 hello
  • 在第 4 行,退出程式
  • 在第 5 行,列印 world
    • 已經執行 sys.exit(0) 退出了程式,不會執行該行程式碼

執行程式:

C:\> python exit.py
hello
C:\>

可以看到,程式列印 hello 後即退出了。

2. sys.argv

2.1 命令列引數

在 windows 和 linux 中,作業系統提供了命令列的控制方式,使用者輸入命令完成任務。例如,建立一個目錄,輸入如下命令:

C:\> mkdir test

這條命令建立了一個名稱為 test 的目錄,字串 ‘mkdir’ 和字串 ‘test’ 被稱為命令列引數。

2.2 Python 程式的命令列引數

Python 將命令列引數儲存在 sys 模組中的 argv 變數中:

  • sys.argv 是一個數組
  • 陣列中儲存的是字串

在命令列模式下,使用 python 直譯器執行程式 program.py

C:\> python program.py argument

則命令列引數 sys.argv 等於 [‘program.py’, ‘argument’],注意:

  • 輸入的命令列由 3 個單詞構成,但是命令列引數不包括 ‘python’
  • 命令列引數包括 python 程式檔名,即 ‘program.py

2.3 例子:回顯所有的引數

編寫程式 echo.py,程式顯示所有的引數:

import sys

for arg in sys.argv:
    print(arg)

程式遍歷陣列 sys.argv,列印陣列中的引數。在命令列中執行程式:

C:\> python echo.py a b c
echo.py
a
b
c

sys.argv 包括 4 個引數:‘echo.py’、‘a’、‘b’、‘c’

2.4 例子:命令列計算器

編寫程式 calc.py,對命令列輸入的表示式進行計算,例如:

C:\> python calc.py 1 + 1
2
C:\> python calc.py 2 - 1
2
  • 在第 1 行,計算 1 + 1 的結果
  • 在第 3 行,計算 2 - 1 的結果

注意:數字和運算子之間必須要有空格

  • 正確的輸入:python calc.py 1 + 1
  • 錯誤的輸入:python calc.py 1+1

程式 calc.py 的程式碼如下:

import sys

if len(sys.argv) != 4:
    print('Usage: python calc.py operand [+|-] operand')
    sys.exit(0)

left = sys.argv[1]
operator = sys.argv[2]
right = sys.argv[3]

if operator == '+':
    print(int(left) + int(right))

if operator == '-':
    print(int(left) - int(right))
  • 在第 3 行,檢查命令列引數個數,正常情況下是 4 個引數
    • 引數 0 是 ‘calc.py
    • 引數 1 是左邊的運算元
    • 引數 2 是操作符
    • 引數 3 是右邊的運算元
  • 在第 7 行到第 9 行,獲取左邊的運算元、操作符、右邊的運算元
  • 在第 11 行,求和
    • 注意,命令列引數是字串,需要使用函式 int(string) 轉換為整數
  • 在第 14 行,相減
    • 注意,命令列引數是字串,需要使用函式 int(string) 轉換為整數

3. 標準輸入、標準輸出、標準出錯

3.1 概述

Python 程式將鍵盤抽象成一個可讀的檔案,從鍵盤讀取使用者輸入,類似於從檔案中讀取資料;Python 程式將螢幕抽象成一個可寫的檔案,向螢幕輸出資料,類似於向檔案中寫資料。

Python 程式執行時會自動開啟三個檔案:

  • 標準輸入檔案(stdin),通常對應終端的鍵盤
  • 標準輸出檔案(stdout),對應終端的螢幕
  • 標準錯誤輸出檔案(stderr),對應終端的螢幕

程式將從標準輸入檔案讀取使用者輸入,將正常輸出資料輸出到標準輸出檔案,而將錯誤資訊輸出到標準錯誤檔案。

3.2 sys.stdin

sys.stdin 是 python 程式的標準輸入,示例如下:

>>> import sys
>>> line = sys.stdin.readline()
abc
>>> line
'abc\n'
  • 在第 2 行,使用 readline() 方法讀取使用者輸入的一行
  • 在第 3 行,使用者輸入 abc

3.3 sys.stdout

sys.stdout 是 python 程式的標準輸出,示例如下:

import sys

sys.stdout.write('www')
sys.stdout.write('imooc')
sys.stdout.write('com')
  • 在第 3 行,使用 write() 方法向螢幕輸出

執行程式,輸出如下:

wwwimooccom

從輸出可以看出,sys.stdout.write(text) 和 print(text) 的區別:

  • print(text) 輸出 text 後會自動換行
  • sys.stdout.write(text) 輸出 text 後不會自動換行

3.4 sys.stderr

sys.stderr 是 python 程式的標準出錯,與 sys.stdout 相比:

  • 兩者都是將資料輸出到螢幕
  • 將正常的資訊輸出到 sys.stdout
  • 將錯誤的資訊輸出到 sys.stderr

3.5 例子:列印下載進度

Python 中的內建函式 print(text) 會自動的加入換行,而在某些場景下,不希望輸出換行,例如,列印下載進度,顯示效果如下:

下載進度

程式在執行的過程中,斷斷續續的輸出如下文字:

  • Downloading 1%
  • Downloading 2%
  • Downloading 100%

如果使用 print(text),就會輸出 100 行,無法達到上圖的效果。

使用 sys.stdout.write(text) 可以控制程式輸出在同一行,程式碼如下:

import sys
import time

for rate in range(100):
    text = 'Downloading %d%%' % rate
    sys.stdout.write(text)
    sys.stdout.write('\r')
    time.sleep(1)    
  • 在第 2 行,引入 time 模組,需要使用 time 模組的 sleep 方法
  • 在第 4 行,使用 for 迴圈模擬下載的過程,總共輸出 100 行文字
    • 在第 6 行,列印當前的下載進度
    • 在第 7 行,輸出 ‘\r’,將游標移動到行首
      • sys.stdout.write(’\r’) 僅僅輸出一個字元 ‘\r’,不會再額外輸出換行
    • 在第 8 行,使用 time.sleep 睡眠 1 秒

4. sys.path

4.1 概述

Python 的模組是一個普通的 Python 檔案,例如 os 模組對應的檔案是 os.py。os 模組是 Python 自帶的模組,如果 Python 安裝到 C:\Python3 目錄下,在 C:\Python3\Lib 目錄下能找到 os.py,即 os.py 的完整路徑是 C:\Python3\Lib\os.py

sys.path 是一個列表,列表儲存了多個路徑名

>>> import sys
>>> sys.path
['C:\\Python3\\DLLs', 'C:\\Python3\\lib', 'C:\\Python3\\lib\\plat-win', 'C:\\Python3\\lib\\lib-tk', 'C:\\Python3', 'C:\\Python3\\lib\\site-packages', 'C:\\Python3\\lib\\site-packages\\win32']

Python 使用 ‘import os’ 引入 os 模組,注意:Python 使用模組名而不是模組的完整路徑引入模組。Python 查詢模組 os 的過程如下:

  • 在 sys.path[0] 指向的目錄 C:\Python3\DLLs 下查詢檔案 os.py
  • 在 sys.path[1] 指向的目錄 C:\Python3\lib 下查詢檔案 os.py

4.2 例子:自定義模組查詢路徑

本節演示如何自定義模組的查詢路徑,例子的目錄結構如下:

目錄結構
  1. 建立目錄 my-modules
mkdir my-modules
  1. 建立檔案 my-modules\utils.py
def add(a, b):
    return a + b

def sub(a, b):
    return a - b
  1. 建立檔案 main.py
import sys
sys.path.append('my-modules')

import utils
print(utils.add(1, 1))
print(utils.sub(2, 1))
  • 在第 2 行,將 my-modules 目錄加入到搜尋路徑中
  • 在第 4 行,通過模組名 utils 匯入模組
    • 匯入模組時,在 sys.path 指定的目錄下查詢 utils.py
    • sys.path 包括目錄 my-modules,因此能找到 utils.py

執行程式,輸出結果:

2
1

5. sys.version

sys.version 記錄了 Python 的版本

如果執行 Python 3:

>>> sys.version
'2.7.0 (v2.7.17, Nov 7 2019, 10:07:09)'

如果執行 Python 2:

>>> sys.version
'3.6.0 (v3.6.0, Dec 23 2016, 08:06:12)'

6. sys.platform

sys.version 記錄了作業系統的型號。

在 windows 中列印 sys.platform:

>>> sys.platform
'win32'

在 linux 中列印 sys.platform:

>>> sys.platform
'linux'