天天看點

《Python程式設計》第二、三章:系統工具、腳本運作上下文

一、《Python程式設計》第二、三章概述

1.概括性介紹與系統程式設計相關的主要子產品,這章介紹最為常用的系統工具,如:os,sys,os.path等

2.os.getcwd、sys.argv、os.environ、sys.stdin、stdout、stderr

二、系統程式設計概述

1.了解python系統子產品

sys、os、os.path是python核心的系統子產品;大多數系統級接口都集中在os和sys子產品,os.path是python解釋器真正的搜尋路徑;其他的标準子產品也屬于系統級子產品,包括:

# glob:用于檔案名擴充
# socket:用于網絡連接配接和程序間通信(IPC)
# threading, _thread,queue:用于運作和同步化并發線程
# time, timeit:用于擷取系統時間及相關細節
# subprocess, multiprocessing:用于啟動和控制并行程序
# signal, select, shutil, tempfile :用于多種 系統相關任務
# 等
# 另外,一些内建函數實際上也是系統接口,例如open函數,就是檔案系統的接口,大體而言,sys和os子產品一起組成了python
# 内置系統工具的核心部分;
           

2.字元串方法基礎知識

#字元串方法基礎知識
#find()#傳回首個比對位置的偏移,比對失敗傳回:-1
mystr = 'yyyyASDjjjjjj'
n=mystr.find('ASD')#傳回首個比對位置的偏移,比對失敗傳回:-1
print(n)

#replace():全局替換
mystr0 = 'aassddffss'
mystr0=mystr0.replace('ss','AA')
print(mystr0)
#字元串搜尋:存在傳回True;不存在,傳回False;類似于find
mystr1 = 'AAAAQWE'
print('AA' in mystr1)#True
print('d' in mystr1)#False
#strip():去除空白分隔符,rstrip()效果類似,隻不過隻是右邊
mystr2 = '\tasdfg\n'
mystr2 = mystr2.strip()
print(mystr2)
mystr2 = '\tasdfg\n'
mystr2 = mystr2.rstrip()
print(mystr2)
#lower()大小寫轉換器
mystr3 = 'AAABBQWE'
mystr3 = mystr3.lower()
print(mystr3)
# isalpha: isalpha() 方法檢測字元串是否隻由字母組成
# isdigit: isdigit() 方法檢測字元串是否隻由數字組成
mystr4="123456"
print(mystr4.isalpha())#False
print(mystr4.isdigit())#True

# string:
import string
s = string.ascii_lowercase
print(s)#abcdefghijklmnopqrstuvwxyz
s = string.ascii_uppercase
print(s)#ABCDEFGHIJKLMNOPQRSTUVWXYZ
s = string.whitespace
print(s.encode("utf-8"))#b' \t\n\r\x0b\x0c'

#split():分隔為子字元串組成的清單
mystr5 = "aaa,bbb,ccc"
mystr5 = mystr5.split(',')
print(mystr5)#['aaa', 'bbb', 'ccc']
mystr5 = 'a b\nc\nd'
mystr5 = mystr5.split()
print(mystr5)#['a', 'b', 'c', 'd']

#連接配接子字元串清單
delim = 'NI'
st=delim.join(['aaa','bbb','ccc'])
print(st)#aaaNIbbbNIccc
#在清單元素間添加空格符,輸入字元串
mystr6 = ' '.join(['aaa','bbb','ccc'])
print(mystr6)#aaa bbb ccc

#轉換為字元組成的清單
chars = list('Lorrtt')
print(chars)#['L', 'o', 'r', 'r', 't', 't']

#生成分隔符:分隔符為空
chars.append("!")#清單追加
ch="".join(chars)
print(ch)#Lorrtt!

#字元串轉換為整型:兩種方式都是
print(int("42"),eval("42"))

#整型轉換為字元串:兩種方式都是
print(type(str(42)),type(repr(42)))

#分别借助格式化表達式和方法
print(type("%d" %42),'{:d}'.format(42))
           

3.os.system、os.popen、subprocess

os.system()隻是簡單的執行一條shell指令行,
# 但os.popen()還會連接配接到指令的标準輸入/輸出流;
listing = os.popen('dir /B').readlines()
print(listing)

#替代方案:subprocess子產品,可以實作os.system;os.popen()相同的效果;一般
# 來說要求更多代碼,但對流的連接配接和使用提供更完善的控制
import subprocess
#模拟os.system()
subprocess.call('python data_004.py') #類似os.system()
subprocess.call('cmd /C "type data_004.py"')#内建shell指令
subprocess.call('type data_004.py',shell=True)#相當于内建函數
#shell指令的局限
#1.shell指令移植性雖好,但卻取決于所運作的指令;例:dir\type在windows可以,在Linux需要改為ls\cat
#2.将python檔案作為程式運作與導入程式檔案再調用其中的函數是截然不同的方式,前者要比後者慢得多(前者通常是在新程序裡執行指令);
#os.startfile
# os.startfile("test.html")#在浏覽器中打開檔案
# os.startfile("技術部-崗位說明書.xlsx")#在microsoft excel中打開
# os.startfile("data_004.py")#python運作檔案
# exec(open("data_004.py",encoding='utf-8').read())#python運作檔案
#os子產品其他函數:
# os.pipe():負責程式間通信
# os.execlp():啟動新程式
# os.mkdir:建立新目錄
# os.mkfifo:建立新的命名管道
# os.remove():根據路徑名删除檔案
# os.stat():擷取檔案底層資訊
# os.open:打開基于底層描述符的檔案
           

三、腳本運作上下文

# python程式可能有各種特定de環境,即程式啟動時,作業系統會自動傳給程式的資訊(如:腳本可以擷取下面幾類系統級的輸入和接口:)
# 目前工作路徑(CWD):
# os.getcwd可以擷取腳本啟動目錄,許多檔案工具隐式地使用該變量;
# 指令行參數
# sys.argv可以擷取在指令行鍵入的啟動參數,将其作為腳本的輸入;
# 标準流
# sys.stdin、stdout、stderr是三個核心的指令行shell工具;可以被print、os.popen、subprocess子產品,io.StringIO類等調用;
           

1.getcwd

# 1.目前工作路徑(CWD):除非指定絕對路徑,否則當腳本處理檔案時,将始終預設它們存在于CWD。
# 腳本可以使用os.getcwd擷取明确的CWD路徑,使用os.chdir改變它的CWD
# 腳本總是啟動于CWD,而不是它所在的目錄;反之,import永遠首先搜尋檔案所在目錄,而非CWD(除非二者是同一目錄);
import os , sys
print('my os.getcwd =>',os.getcwd())
print('my sys.path =>',sys.path)

# 2.CWD,檔案和import路徑
# 無論你在哪個目錄運作py檔案,即:不管CWD是什麼,python都會把你運作的py檔案所在目錄添加到sys.path(子產品搜尋路徑)的最前面;
# 是以,你可以随意調用py檔案所在目錄的其他py檔案中的腳步;
           

2.argv

# 4.指令行參數
# python可以通過sys子產品擷取腳步啟動時指令行輸入的資訊,稱為指令行參數,以内置字元串清單的形式存于sys.argv中;
# 指令行參數通過位置或使用‘-name value’詞語組來傳遞;
print(sys.argv)
           

2.1 解析指令行參數

def getopts(argv):
    opts = {}
    while argv:
        # 判斷argv清單的索引為0的元素是否是指令行參數的參數名;
        # 若參數字元串的索引0位置為“-”,則該參數是鍵;索引為1的argv的元素則為值
        if argv[0][0] == '-':
            opts[argv[0]] =argv[1]
            # 去掉已經指派到字典中的索引為0,1的元素,形成新的清單,再次循環,直到[]循環停止;
            # 注意:清單索引不可超過清單長度;但是切片可以超過清單長度;超過則是空清單
            argv = argv[2:]
        else:
            argv =argv[1:]#若argv清單中的索引0号元素不是指令行參數,則從下一個元素開始再次循環;
    return opts
if __name__ == '__main__':
     from sys import argv
     print(argv)
     myargs = getopts(argv)
     if "-i" in myargs:
         print(myargs['-i'])
     print(myargs)
#在指令行運作該檔案,入指令行參數 -i data.txt -o result.txt
           

3. shell變量

# shell環境變量
# shell變量有時稱之為環境變量,python可以通過類似python字典的對象os.environ來通路;
# os.environ對象裡每項對應一個shell的變量設定;
# shell變量通常在系統啟動、startup檔案、控制台中設定;它能為系統提供系統級的配置

# 1.擷取shell變量---》
# import os,pprint
# # print(os.environ.keys())#類似python字典的對象
# # pprint.pprint(list(os.environ.keys()))#隻有字典key組成的清單
# # pprint.pprint(list(os.environ.values()))#隻有字典Value組成的清單
# # print(os.environ['TMP'])#取字典中的某一個關鍵字的值
#
# # pprint.pprint(os.environ['PYTHONPATH'])
#
# for r in os.environ['PYTHONPATH'].split(os.pathsep):
#     print(r)
#     print(os.pathsep)#os.path的分隔符,自動識别目标平台(DOS/Windows為逗号;Linux/Unix為冒号)
# 2.修改shell變量
import os,subprocess
import pprint
print('setenv……', end="")
pprint.pprint(list(os.environ))
print(os.environ['USERNAME'])
os.environ['USERNAME'] = 'ithing'
print(os.environ['USERNAME'])
# 注意:一個子程式始終從它的父程序那裡繼承環境設定;
# 在Unix下,os.spawnx、os.fork/exec;或者所有平台下的os.popen、os.system、subprocess在啟動時都會獲得父程序的環境變量
# pprint.pprint(list(os.environ))
# 3.shell變量要點:父程序、putenv、getenv
# 你的程式中對shell所做的設定隻對程式本身及其衍生的子程式有效,程式關閉後;失效;
           

4.标準流、重定向

# 标準流
# import sys
#
# for f in (sys.stdin,sys.stdout,sys.stderr):print(f)
# # 标準流:sys.stdin、sys.stdout、sys.stderr;它們是又一通用的通信方式。
# # 标準流是預先打開的python檔案對象;它們在python啟動時自動連接配接到你的程式上;
# # 預設在python啟動時被綁定到控制台視窗。
# # 内部的print和input函數實際上隻是标準輸出/輸入流的接口;是以他們的使用類似;
# print('hello stdout world')
# sys.stdout.write('hello stdout world')
#
# input('hello stdout world')
# print('hello stdout world')
# sys.stdin.readline()[:]

# 重定向
# 重定向标準輸入流到不同檔案,可以将一個測試腳本應用于任意的輸入
# 重定向标準輸出流使得我們能夠儲存及後續分析一個程式的輸出
def interact():
    '''
    這是一個根據輸入數字,運算出平方,然後輸出結果的函數;
    :return:
    '''
    print('start……')
    while True:
        try:
            reply = input('Enter a number:')
        except EOFError:
            break
        else:
            num = int(reply)
            print("%d squared is %d" %(num,num**2))
    print("bye")

if __name__ == '__main__':
    interact()

# input.txt檔案中,已預備了數字,作為輸入内容
# output.txt檔案作為接受結果的檔案
# < filename:把标準輸入流重定向到檔案輸入
# > filename:把标準輸出流重定向到檔案中;
# 在指令提示符中,python 4.py < input > output
           

5、用管道符(pipe)連結程式

知識點總結:不管有幾個程式通過管道符連結,上遊程式的輸出都會通過shell管道成為下遊程式的輸入;

預置條件:1、2;結果:3

1.在writer.py檔案中:

《Python程式設計》第二、三章:系統工具、腳本運作上下文

2.在reader.py檔案中:

《Python程式設計》第二、三章:系統工具、腳本運作上下文

3.指令行執行:

《Python程式設計》第二、三章:系統工具、腳本運作上下文