subprocess模塊怎么使用
subprocess模塊主要用于創(chuàng)建子進程,并連接它們的輸入、輸出和錯誤管道,獲取它們的返回狀態(tài)。通俗地說就是通過這個模塊,你可以在Python的代碼里執(zhí)行操作系統(tǒng)級別的命令,比如ipconfig、du-sh等。
subprocess模塊替代了一些老的模塊和函數,比如:os.system、os.spawn*等。
subprocess過去版本中的call(),check_call()和check_output()已經被run()方法取代了。run()方法為3.5版本新增。
大多數情況下,推薦使用run()方法調用子進程,執(zhí)行操作系統(tǒng)命令。在更高級的使用場景,你還可以使用Popen接口。其實run()方法在底層調用的就是Popen接口。
subprocess.run
subprocess.run(args,*,stdin=None,input=None,stdout=None,stderr=None,shell=False,timeout=None,check=False,encoding=None,errors=None)
功能:執(zhí)行args參數所表示的命令,等待命令結束,并返回一個CompletedProcess類型對象。
注意,run()方法返回的不是我們想要的執(zhí)行結果或相關信息,而是一個CompletedProcess類型對象。
上面參數表里展示的只是一些常用的,真實情況還有很多。
args:表示要執(zhí)行的命令,必須是一個字符串,字符串參數列表。
stdin、stdout和stderr:子進程的標準輸入、輸出和錯誤。其值可以是subprocess.PIPE、subprocess.DEVNULL、一個已經存在的文件描述符、已經打開的文件對象或者None。
subprocess.PIPE表示為子進程創(chuàng)建新的管道,subprocess.DEVNULL表示使用os.devnull。默認使用的是None,表示什么都不做。另外,stderr可以合并到stdout里一起輸出。
timeout:設置命令超時時間。如果命令執(zhí)行時間超時,子進程將被殺死,并彈出TimeoutExpired異常。
check:如果該參數設置為True,并且進程退出狀態(tài)碼不是0,則彈出CalledProcessError異常。
encoding:如果指定了該參數,則stdin、stdout和stderr可以接收字符串數據,并以該編碼方式編碼。否則只接收bytes類型的數據。
shell:如果該參數為True,將通過操作系統(tǒng)的shell執(zhí)行指定的命令。
看下面的例子:
>>>subprocess.run(["ls","-l"])#沒有對輸出進行捕獲CompletedProcess(args=['ls','-l'],returncode=0)>>>subprocess.run("exit1",shell=True,check=True)Traceback(mostrecentcalllast):...subprocess.CalledProcessError:Command'exit1'returnednon-zeroexitstatus1>>>subprocess.run(["ls","-l","/dev/null"],stdout=subprocess.PIPE)CompletedProcess(args=['ls','-l','/dev/null'],returncode=0,stdout=b'crw-rw-rw-1rootroot1,3Jan2316:23/dev/null\n')>>>subprocess.run("python--version",stdout=subprocess.PIPE)CompletedProcess(args='python--version',returncode=0,stdout=b'Python3.6.1\r\n')>>>s=subprocess.run("ipconfig",stdout=subprocess.PIPE)#捕獲輸出>>>print(s.stdout.decode("GBK"))
subprocess.CompletedProcess
run()方法的返回值,表示一個進程結束了。CompletedProcess類有下面這些屬性:
args啟動進程的參數,通常是個列表或字符串。
returncode進程結束狀態(tài)返回碼。0表示成功狀態(tài)。
stdout獲取子進程的stdout。通常為bytes類型序列,None表示沒有捕獲值。如果你在調用run()方法時,設置了參數stderr=subprocess.STDOUT,則錯誤信息會和stdout一起輸出,此時stderr的值是None。
stderr獲取子進程的錯誤信息。通常為bytes類型序列,None表示沒有捕獲值。
check_returncode()用于檢查返回碼。如果返回狀態(tài)碼不為零,彈出CalledProcessError異常。
subprocess.DEVNULL
一個特殊值,用于傳遞給stdout、stdin和stderr參數。表示使用os.devnull作為參數值。
subprocess.PIPE
管道,可傳遞給stdout、stdin和stderr參數。
subprocess.STDOUT
特殊值,可傳遞給stderr參數,表示stdout和stderr合并輸出。
args與shell
args參數可以接收一個類似'du-sh'的字符串,也可以傳遞一個類似['du','-sh']的字符串分割列表。shell參數默認為False,設置為True的時候表示使用操作系統(tǒng)的shell執(zhí)行命令。
下面我們來看一下兩者的組合結果。
In[14]:subprocess.run('du-sh')---------------------------------------------------------------------------FileNotFoundErrorTraceback(mostrecentcalllast)......FileNotFoundError:[Errno2]Nosuchfileordirectory:'du-sh'In[15]:subprocess.run('du-sh',shell=True)175M.Out[15]:CompletedProcess(args='du-sh',returncode=0)
可見,在Linux環(huán)境下,當args是個字符串時,必須指定shell=True。成功執(zhí)行后,返回一個CompletedProcess對象。
In[16]:subprocess.run(['du','-sh'],shell=True).....大量的數據4./文檔179100.Out[16]:CompletedProcess(args=['du','-sh'],returncode=0)In[17]:subprocess.run(['du','-sh'])175M.Out[17]:CompletedProcess(args=['du','-sh'],returncode=0)
可見,當args是一個['du','-sh']列表,并且shell=True的時候,參數被忽略了,只執(zhí)行不帶參數的du命令。
總結:Linux中,當args是個字符串是,請設置shell=True,當args是個列表的時候,shell保持默認的False。
獲取執(zhí)行結果
run()方法返回的是一個CompletedProcess類型對象,不能直接獲取我們通常想要的結果。要獲取命令執(zhí)行的結果或者信息,在調用run()方法的時候,請指定stdout=subprocess.PIPE。
>>>ret=subprocess.run('dir',shell=True)>>>retCompletedProcess(args='dir',returncode=0)>>>ret=subprocess.run('dir',shell=True,stdout=subprocess.PIPE)>>>retCompletedProcess(args='dir',returncode=0,stdout=b'\xc7\xfd\xb6\xaf\xc6\xf7......')>>>ret.stdoutb'\xc7\xfd\xb6\xaf\xc6\xf7C\xd6\xd0\xb5\xc4\xbe\xed\xca\xc7......'
從例子中我們可以看到,如果不設置stdout=subprocess.PIPE,那么在返回值CompletedProcess(args='dir',returncode=0)中不會包含stdout屬性。反之,則會將結果以bytes類型保存在ret.stdout屬性中。
交互式輸入
并不是所有的操作系統(tǒng)命令都像‘dir’或者‘ipconfig’那樣單純地返回執(zhí)行結果,還有很多像‘python’這種交互式的命令,你要輸入點什么,然后它返回執(zhí)行的結果。使用run()方法怎么向stdin里輸入?
這樣?
importsubprocessret=subprocess.run("python",stdin=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)ret.stdin="print('haha')"#錯誤的用法print(ret)
這樣是不行的,ret作為一個CompletedProcess對象,根本沒有stdin屬性。那怎么辦呢?前面說了,run()方法的stdin參數可以接收一個文件句柄。比如在一個1.txt文件中寫入print('ilikePython')。然后參考下面的使用方法:
importsubprocessfd=open("d:\\1.txt")ret=subprocess.run("python",stdin=fd,stdout=subprocess.PIPE,shell=True)print(ret.stdout)fd.close()
這樣做,雖然可以達到目的,但是很不方便,也不是以代碼驅動的方式。這個時候,我們可以使用Popen類。
subprocess.Popen()
用法和參數與run()方法基本類同,但是它的返回值是一個Popen對象,而不是CompletedProcess對象。
>>>ret=subprocess.Popen("dir",shell=True)>>>type(ret)<class'subprocess.Popen'>>>>ret<subprocess.Popenobjectat0x0000000002B17668>
Popen對象的stdin、stdout和stderr是三個文件句柄,可以像文件那樣進行讀寫操作。
>>>s=subprocess.Popen("ipconfig",stdout=subprocess.PIPE,shell=True)>>>print(s.stdout.read().decode("GBK"))
要實現前面的‘python’命令功能,可以按下面的例子操作:
importsubprocesss=subprocess.Popen("python",stdout=subprocess.PIPE,stdin=subprocess.PIPE,shell=True)s.stdin.write(b"importos\n")s.stdin.write(b"print(os.environ)")s.stdin.close()out=s.stdout.read().decode("GBK")s.stdout.close()print(out)
通過s.stdin.write()可以輸入數據,而s.stdout.read()則能輸出數據。
python需要標準嗎
如果沒有特殊的編碼要求,建議在文件頭部加一行#-*-encoding:utf-8-*-標識,聲明文件的編碼方式,當然,程序文件的編碼要和聲明的編碼保持一致,使用UTF-8編碼。
2.縮進/空格/空行/換行等基本格式
縮進:統(tǒng)一使用4個空格進行縮進。通常使用1個Tab鍵,但Tab鍵不一定使4個空格鍵,所以有時候因此出錯。
行寬:每行代碼盡量不超過80個字符,但不是嚴格要求80字符以內,可略微查過。如果代碼過長,說明代碼設計不太合理。除此之外也方便于在控制臺查看代碼以及通過對side-by-side的diff時有幫助。
pythonglob和loop的用法
找到目錄中的文件(或目錄)名,判斷其是不是目錄,如果是目錄再遍歷子目錄。你說的loop應該是循環(huán)的意思。importosimportglobd=u'd:\\7-zip\\'defloop(path):files=glob.glob1(path,'*')printfilesforfileinfiles:ifos.path.isdir(os.path.join(path,file)):loop(os.path.join(path,file))loop(d)
python用記事本中的名字給文件批量命名
#@File:011_批量重命名文件.py
#@Software:PyCharm
importos
#1.獲取一個要重命名的文件夾的名字
folder_name=input("請輸入要重命名的文件夾:")
#2.獲取那個文件夾中所有的文件名字
file_names=os.listdir(folder_name)
#第1中方法
#os.chdir(folder_name)
#3.對獲取的名字進行重命名即可
#fornameinfile_names:
#print(name)
#os.rename(name,"[京東出品]-"+name)
i=1#可以讓每個文件名字都不一樣
fornameinfile_names:
print(name)
print(name.split('[京東出品]-')[-1])
name1=name.split('[京東出品]-')[-1]
old_file_name="./"+folder_name+"/"+name
new_file_name="./"+folder_name+"/"+str(i)+"[京東出品]-"+name1
os.rename(old_file_name,new_file_name)
i+=1
python中speak的用法
在Python中,"speak"并不是內置的函數或方法,因此您需要使用第三方庫或模塊來執(zhí)行語音合成任務。以下是使用Python中的兩種常見語音合成庫的示例:
使用pyttsx3庫進行語音合成:
首先,您需要使用pip安裝pyttsx3庫。在安裝完成后,您可以使用以下代碼進行語音合成:
python
復制
importpyttsx3
#創(chuàng)建語音引擎
engine=pyttsx3.init()
#設置要合成的文本
text="Hello,world!"
#執(zhí)行語音合成
engine.say(text)
engine.runAndWait()
這將使用默認語音和語速進行語音合成,并將音頻輸出到默認音頻設備。
使用gTTS庫進行語音合成:
首先,您需要使用pip安裝gTTS庫。在安裝完成后,您可以使用以下代碼進行語音合成:
python
復制
fromgttsimportgTTS
importos
#創(chuàng)建語音引擎
engine=gTTS("Hello,world!")
#設置要合成的文本
text="Hello,world!"
#生成音頻文件
engine.save("audio.mp3")
#播放音頻文件
os.system("mpg321audio.mp3")
這將使用gTTS庫將文本轉換為語音,并將生成的音頻文件保存為"audio.mp3"。然后,使用os模塊的system函數播放音頻文件。請注意,您需要在計算機上安裝相應的音頻播放器才能播放音頻文件。
python獲得文件創(chuàng)建時間和修改時間的方法
我們通過文件屬性的獲取,os.stat()方法:>>>importos>>>statinfo=os.stat(r"C:/1.txt")>>>statinfo(33206,0L,0,0,0,0,29L,1201865413,1201867904,1201865413)使用os.stat的返回值statinfo的三個屬性獲取文件的創(chuàng)建時間等st_atime(訪問時間),st_mtime(修改時間),st_ctime(創(chuàng)建時間),例如,取得文件修改時間:>>>statinfo.st_mtime1201865413.8952832這個時間是一個linux時間戳,需要轉換一下使用time模塊中的localtime函數可以知道:>>>importtime>>>time.localtime(statinfo.st_ctime)(2008,2,1,19,30,13,4,32,0)2008年2月1日的19時30分13秒(2008-2-119:30:13)