小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Python 常用模塊大全(整理)-CSDN博客

 nxhujiee 2024-08-21 發(fā)布于寧夏
OS 模塊
#os模塊就是對(duì)操作系統(tǒng)進(jìn)行操作,使用該模塊必須先導(dǎo)入模塊: import os

#getcwd() 獲取當(dāng)前工作目錄(當(dāng)前工作目錄默認(rèn)都是當(dāng)前文件所在的文件夾) result = os.getcwd() print(result)

#chdir()改變當(dāng)前工作目錄 os.chdir('/home/sy') result = os.getcwd() print(result)

open('02.txt','w')

#操作時(shí)如果書(shū)寫(xiě)完整的路徑則不需要考慮默認(rèn)工作目錄的問(wèn)題,按照實(shí)際書(shū)寫(xiě)路徑操作 open('/home/sy/下載/02.txt','w')

#listdir() 獲取指定文件夾中所有內(nèi)容的名稱列表 result = os.listdir('/home/sy') print(result)

#mkdir() 創(chuàng)建文件夾 #os.mkdir('girls') #os.mkdir('boys',0o777)

#makedirs() 遞歸創(chuàng)建文件夾 #os.makedirs('/home/sy/a/b/c/d')

#rmdir() 刪除空目錄 #os.rmdir('girls')

#removedirs 遞歸刪除文件夾 必須都是空目錄 #os.removedirs('/home/sy/a/b/c/d')

#rename() 文件或文件夾重命名 #os.rename('/home/sy/a','/home/sy/alibaba' #os.rename('02.txt','002.txt')

#stat() 獲取文件或者文件夾的信息 #result = os.stat('/home/sy/PycharmProject/Python3/10.27/01.py) #print(result)

#system() 執(zhí)行系統(tǒng)命令(危險(xiǎn)函數(shù)) #result = os.system('ls -al') #獲取隱藏文件 #print(result)

#環(huán)境變量 ''' 環(huán)境變量就是一些命令的集合 操作系統(tǒng)的環(huán)境變量就是操作系統(tǒng)在執(zhí)行系統(tǒng)命令時(shí)搜索命令的目錄的集合 ''' #getenv() 獲取系統(tǒng)的環(huán)境變量 result = os.getenv('PATH') print(result.split(':'))

#putenv() 將一個(gè)目錄添加到環(huán)境變量中(臨時(shí)增加僅對(duì)當(dāng)前腳本有效) #os.putenv('PATH','/home/sy/下載') #os.system('syls')

#exit() 退出終端的命令

#os模塊中的常用值 #curdir 表示當(dāng)前文件夾 .表示當(dāng)前文件夾 一般情況下可以省略 print(os.curdir)

#pardir 表示上一層文件夾 ..表示上一層文件夾 不可省略! print(os.pardir)

#os.mkdir('../../../man')#相對(duì)路徑 從當(dāng)前目錄開(kāi)始查找 #os.mkdir('/home/sy/man1')#絕對(duì)路徑 從根目錄開(kāi)始查找

#name 獲取代表操作系統(tǒng)的名稱字符串 print(os.name) #posix -> linux或者unix系統(tǒng) nt -> window系統(tǒng)

#sep 獲取系統(tǒng)路徑間隔符號(hào) window ->\ linux ->/ print(os.sep)

#extsep 獲取文件名稱和后綴之間的間隔符號(hào) window & linux -> . print(os.extsep)

#linesep 獲取操作系統(tǒng)的換行符號(hào) window -> \r\n linux/unix -> \n print(repr(os.linesep))

#導(dǎo)入os模塊 import os

#以下內(nèi)容都是os.path子模塊中的內(nèi)容

#abspath() 將相對(duì)路徑轉(zhuǎn)化為絕對(duì)路徑 path = './boys'#相對(duì) result = os.path.abspath(path) print(result)

#dirname() 獲取完整路徑當(dāng)中的目錄部分 & basename()獲取完整路徑當(dāng)中的主體部分 path = '/home/sy/boys' result = os.path.dirname(path) print(result)

result = os.path.basename(path) print(result)

#split() 將一個(gè)完整的路徑切割成目錄部分和主體部分 path = '/home/sy/boys' result = os.path.split(path) print(result)

#join() 將2個(gè)路徑合并成一個(gè) var1 = '/home/sy' var2 = '000.py' result = os.path.join(var1,var2) print(result)

#splitext() 將一個(gè)路徑切割成文件后綴和其他兩個(gè)部分,主要用于獲取文件的后綴 path = '/home/sy/000.py' result = os.path.splitext(path) print(result)

#getsize() 獲取文件的大小 #path = '/home/sy/000.py' #result = os.path.getsize(path) #print(result)

#isfile() 檢測(cè)是否是文件 path = '/home/sy/000.py' result = os.path.isfile(path) print(result)

#isdir() 檢測(cè)是否是文件夾 result = os.path.isdir(path) print(result)

#islink() 檢測(cè)是否是鏈接 path = '/initrd.img.old' result = os.path.islink(path) print(result)

#getctime() 獲取文件的創(chuàng)建時(shí)間 get create time #getmtime() 獲取文件的修改時(shí)間 get modify time #getatime() 獲取文件的訪問(wèn)時(shí)間 get active time

import time

filepath = '/home/sy/下載/chls'

result = os.path.getctime(filepath) print(time.ctime(result))

result = os.path.getmtime(filepath) print(time.ctime(result))

result = os.path.getatime(filepath) print(time.ctime(result))

#exists() 檢測(cè)某個(gè)路徑是否真實(shí)存在 filepath = '/home/sy/下載/chls' result = os.path.exists(filepath) print(result)

#isabs() 檢測(cè)一個(gè)路徑是否是絕對(duì)路徑 path = '/boys' result = os.path.isabs(path) print(result)

#samefile() 檢測(cè)2個(gè)路徑是否是同一個(gè)文件 path1 = '/home/sy/下載/001' path2 = '../../../下載/001' result = os.path.samefile(path1,path2) print(result)

#os.environ 用于獲取和設(shè)置系統(tǒng)環(huán)境變量的內(nèi)置值 import os #獲取系統(tǒng)環(huán)境變量 getenv() 效果 print(os.environ['PATH'])

#設(shè)置系統(tǒng)環(huán)境變量 putenv() os.environ['PATH'] += ':/home/sy/下載' os.system('chls')

os 常用方法

 
  

os.remove('path/filename’) 刪除文件

 
  

os.rename(oldname, newname) 重命名文件

 
  

os.walk() 生成目錄樹(shù)下的所有文件名

 
  

os.chdir('dirname') 改變目錄

 
  

os.mkdir/makedirs('dirname')創(chuàng)建目錄/多層目錄

 
  

os.rmdir/removedirs('dirname') 刪除目錄/多層目錄

 
  

os.listdir('dirname') 列出指定目錄的文件

 
  

os.getcwd() 取得當(dāng)前工作目錄

 
  

os.chmod() 改變目錄權(quán)限

 
  

os.path.basename('path/filename’) 去掉目錄路徑,返回文件名

 
  

os.path.dirname('path/filename’) 去掉文件名,返回目錄路徑

 
  

os.path.join(path1[,path2[,...]]) 將分離的各部分組合成一個(gè)路徑名

 
  

os.path.split('path') 返回( dirname(), basename())元組

 
  

os.path.splitext() 返回 (filename, extension) 元組

 
  

os.path.getatime\ctime\mtime 分別返回最近訪問(wèn)、創(chuàng)建、修改時(shí)間

 
  

os.path.getsize() 返回文件大小

 
  

os.path.exists() 是否存在

 
  

os.path.isabs() 是否為絕對(duì)路徑

 
  

os.path.isdir() 是否為目錄

 
  

os.path.isfile() 是否為文件

 
  

 sys 模塊

 
  

sys.argv 命令行參數(shù)List,第一個(gè)元素是程序本身路徑

 
  

sys.modules.keys() 返回所有已經(jīng)導(dǎo)入的模塊列表

 
  

sys.exc_info() 獲取當(dāng)前正在處理的異常類,exc_type、exc_value、exc_traceback當(dāng)前處理的異常詳細(xì)信息

 
  

sys.exit(n) 退出程序,正常退出時(shí)exit(0)

 
  

sys.hexversion 獲取Python解釋程序的版本值,16進(jìn)制格式如:0x020403F0

 
  

sys.version 獲取Python解釋程序的版本信息

 
  

sys.maxint 最大的Int值

 
  

sys.maxunicode 最大的Unicode值

 
  

sys.modules 返回系統(tǒng)導(dǎo)入的模塊字段,key是模塊名,value是模塊

 
  

sys.path 返回模塊的搜索路徑,初始化時(shí)使用PYTHONPATH環(huán)境變量的值

 
  

sys.platform 返回操作系統(tǒng)平臺(tái)名稱

 
  

sys.stdout 標(biāo)準(zhǔn)輸出

 
  

sys.stdin 標(biāo)準(zhǔn)輸入

 
  

sys.stderr 錯(cuò)誤輸出

 
  

sys.exc_clear() 用來(lái)清除當(dāng)前線程所出現(xiàn)的當(dāng)前的或最近的錯(cuò)誤信息

 
  

sys.exec_prefix 返回平臺(tái)獨(dú)立的python文件安裝的位置

 
  

sys.byteorder 本地字節(jié)規(guī)則的指示器,big-endian平臺(tái)的值是'big',little-endian平臺(tái)的值是'little'

 
  

sys.copyright 記錄python版權(quán)相關(guān)的東西

 
  

sys.api_version 解釋器的C的API版本

 
  

 

 
  

 

 
  

sys.stdin,sys.stdout,sys.stderr

 
  
stdin , stdout , 以及stderr 變量包含與標(biāo)準(zhǔn)I/O 流對(duì)應(yīng)的流對(duì)象. 如果需要更好地控制輸出,而print 不能滿足你的要求, 它們就是你所需要的. 你也可以替換它們, 這時(shí)候你就可以重定向輸出和輸入到其它設(shè)備( device ), 或者以非標(biāo)準(zhǔn)的方式處理它們
 
  
我們常用print和raw_input來(lái)進(jìn)行輸入和打印,那么print 和 raw_input是如何與標(biāo)準(zhǔn)輸入/輸出流建立關(guān)系的呢?
其實(shí)Python程序的標(biāo)準(zhǔn)輸入/輸出/出錯(cuò)流定義在sys模塊中,分別 為: sys.stdin,sys.stdout, sys.stderr
下列的程序也可以用來(lái)輸入和輸出是一樣的:
import sys

sys.stdout.write('HelloWorld!')

print 'Please enter yourname:',
name=sys.stdin.readline()[:-1]
print 'Hi, %s!' % name

那么sys.stdin, sys.stdout, stderr到底是什么呢?我們?cè)赑ython運(yùn)行環(huán)境中輸入以下代碼:
import sys
for f in (sys.stdin,sys.stdout, sys.stderr): print f
輸出為:
<open file'<stdin>', mode 'r' at 892210>
<open file'<stdout>', mode 'w' at 892270>
<open file'<stderr>', mode 'w at 8922d0>

由此可以看出stdin, stdout, stderr在Python中無(wú)非都是文件屬性的對(duì)象,他們?cè)赑ython啟動(dòng)時(shí)自動(dòng)與Shell 環(huán)境中的標(biāo)準(zhǔn)輸入,輸出,出錯(cuò)關(guān)聯(lián)。
而Python程序的在Shell中的I/O重定向與本文開(kāi)始時(shí)舉的DOS命令的重定向完全相同,其實(shí)這種重定向是由Shell來(lái)提供的,與Python 本身并無(wú)關(guān)系。那么我們是否可以在Python程序內(nèi)部將stdin,stdout,stderr讀寫(xiě)操作重定向到一個(gè)內(nèi)部對(duì)象呢?答案是肯定的。
Python提供了一個(gè)StringIO模塊來(lái)完成這個(gè)設(shè)想,比如:
from StringIO import StringIO
import sys
buff =StringIO()

temp =sys.stdout                              #保存標(biāo)準(zhǔn)I/O流
sys.stdout =buff                                #將標(biāo)準(zhǔn)I/O流重定向到buff對(duì)象
print 42, 'hello', 0.001

sys.stdout=temp                                #恢復(fù)標(biāo)準(zhǔn)I/O流
print buff.getvalue()
time模塊

 time模塊中時(shí)間表現(xiàn)的格式主要有三種:

  a、timestamp時(shí)間戳,時(shí)間戳表示的是從1970年1月1日00:00:00開(kāi)始按秒計(jì)算的偏移量

  b、struct_time時(shí)間元組,共有九個(gè)元素組。

  c、format time 格式化時(shí)間,已格式化的結(jié)構(gòu)使時(shí)間更具可讀性。包括自定義格式和固定格式。

1、時(shí)間格式轉(zhuǎn)換圖:

 

2、主要time生成方法和time格式轉(zhuǎn)換方法實(shí)例:

復(fù)制代碼
復(fù)制代碼
#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ" 

import time

# 生成timestamp time.time() # 1477471508.05
#struct_time to timestamp
time.mktime(time.localtime())

#生成struct_time
# timestamp to struct_time 本地時(shí)間
time.localtime()
time.localtime(time.time())
# time.struct_time(tm_year=2016, tm_mon=10, tm_mday=26, tm_hour=16, tm_min=45, tm_sec=8, tm_wday=2, tm_yday=300, tm_isdst=0) # timestamp to struct_time 格林威治時(shí)間 time.gmtime() time.gmtime(time.time()) # time.struct_time(tm_year=2016, tm_mon=10, tm_mday=26, tm_hour=8, tm_min=45, tm_sec=8, tm_wday=2, tm_yday=300, tm_isdst=0) #format_time to struct_time time.strptime('2011-05-05 16:37:06', '%Y-%m-%d %X') # time.struct_time(tm_year=2011, tm_mon=5, tm_mday=5, tm_hour=16, tm_min=37, tm_sec=6, tm_wday=3, tm_yday=125, tm_isdst=-1) #生成format_time #struct_time to format_time time.strftime("%Y-%m-%d %X") time.strftime("%Y-%m-%d %X",time.localtime()) # 2016-10-26 16:48:41 #生成固定格式的時(shí)間表示格式 time.asctime(time.localtime()) time.ctime(time.time()) # Wed Oct 26 16:45:08 2016
復(fù)制代碼
復(fù)制代碼

struct_time元組元素結(jié)構(gòu)

復(fù)制代碼
復(fù)制代碼
屬性                            值
tm_year(年)                  比如2011 
tm_mon(月)                   1 - 12
tm_mday(日)                  1 - 31 tm_hour(時(shí)) 0 - 23 tm_min(分) 0 - 59 tm_sec(秒) 0 - 61 tm_wday(weekday) 0 - 6(0表示周日) tm_yday(一年中的第幾天) 1 - 366 tm_isdst(是否是夏令時(shí)) 默認(rèn)為-1
復(fù)制代碼
復(fù)制代碼

 

format time結(jié)構(gòu)化表示

格式含義
%a本地(locale)簡(jiǎn)化星期名稱
%A本地完整星期名稱
%b本地簡(jiǎn)化月份名稱
%B本地完整月份名稱
%c本地相應(yīng)的日期和時(shí)間表示
%d一個(gè)月中的第幾天(01 - 31)
%H一天中的第幾個(gè)小時(shí)(24小時(shí)制,00 - 23)
%I第幾個(gè)小時(shí)(12小時(shí)制,01 - 12)
%j一年中的第幾天(001 - 366)
%m月份(01 - 12)
%M分鐘數(shù)(00 - 59)
%p本地am或者pm的相應(yīng)符
%S秒(01 - 61)
%U一年中的星期數(shù)。(00 - 53星期天是一個(gè)星期的開(kāi)始。)第一個(gè)星期天之前的所有天數(shù)都放在第0周。
%w一個(gè)星期中的第幾天(0 - 6,0是星期天)
%W和%U基本相同,不同的是%W以星期一為一個(gè)星期的開(kāi)始。
%x本地相應(yīng)日期
%X本地相應(yīng)時(shí)間
%y去掉世紀(jì)的年份(00 - 99)
%Y完整的年份
%Z時(shí)區(qū)的名字(如果不存在為空字符)
%%'%’字符

 

常見(jiàn)結(jié)構(gòu)化時(shí)間組合:

print time.strftime("%Y-%m-%d %X")
#2016-10-26 20:50:13

 3、time加減

復(fù)制代碼
復(fù)制代碼
#timestamp加減單位以秒為單位
import time
t1 = time.time()
t2=t1+10

print time.ctime(t1)#Wed Oct 26 21:15:30 2016 print time.ctime(t2)#Wed Oct 26 21:15:40 2016

復(fù)制代碼
復(fù)制代碼

 

datetime模塊

datatime模塊重新封裝了time模塊,提供更多接口,提供的類有:date,time,datetime,timedelta,tzinfo。

1、date類

datetime.date(year, month, day)

靜態(tài)方法和字段

date.max、date.min:date對(duì)象所能表示的最大、最小日期;
date.resolution:date對(duì)象表示日期的最小單位。這里是天。
date.today():返回一個(gè)表示當(dāng)前本地日期的date對(duì)象;
date.fromtimestamp(timestamp):根據(jù)給定的時(shí)間戮,返回一個(gè)date對(duì)象;
output

 

方法和屬性

復(fù)制代碼
復(fù)制代碼
d1 = date(2011,06,03)#date對(duì)象
d1.year、date.month、date.day:年、月、日;
d1.replace(year, month, day):生成一個(gè)新的日期對(duì)象,用參數(shù)指定的年,月,日代替原有對(duì)象中的屬性。(原有對(duì)象仍保持不變)
d1.timetuple():返回日期對(duì)應(yīng)的time.struct_time對(duì)象;
d1.weekday():返回weekday,如果是星期一,返回0;如果是星期2,返回1,以此類推;
d1.isoweekday():返回weekday,如果是星期一,返回1;如果是星期2,返回2,以此類推;
d1.isocalendar():返回格式如(year,month,day)的元組;
d1.isoformat():返回格式如'YYYY-MM-DD’的字符串;
d1.strftime(fmt):和time模塊format相同。
復(fù)制代碼
復(fù)制代碼
output

 

2、time類

datetime.time(hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ) 

靜態(tài)方法和字段

time.min、time.max:time類所能表示的最小、最大時(shí)間。其中,time.min = time(0, 0, 0, 0), time.max = time(23, 59, 59, 999999);
time.resolution:時(shí)間的最小單位,這里是1微秒;

 

方法和屬性

復(fù)制代碼
復(fù)制代碼
t1 = datetime.time(10,23,15)#time對(duì)象
t1.hour、t1.minute、t1.second、t1.microsecond:時(shí)、分、秒、微秒; t1.tzinfo:時(shí)區(qū)信息; t1.replace([ hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ] ):創(chuàng)建一個(gè)新的時(shí)間對(duì)象,用參數(shù)指定的時(shí)、分、秒、微秒代替原有對(duì)象中的屬性(原有對(duì)象仍保持不變); t1.isoformat():返回型如"HH:MM:SS"格式的字符串表示; t1.strftime(fmt):同time模塊中的format;
復(fù)制代碼
復(fù)制代碼
output

3、datetime類

datetime相當(dāng)于date和time結(jié)合起來(lái)。
datetime.datetime (year, month, day[ , hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ] )

靜態(tài)方法和字段

復(fù)制代碼
復(fù)制代碼
datetime.today():返回一個(gè)表示當(dāng)前本地時(shí)間的datetime對(duì)象;
datetime.now([tz]):返回一個(gè)表示當(dāng)前本地時(shí)間的datetime對(duì)象,如果提供了參數(shù)tz,則獲取tz參數(shù)所指時(shí)區(qū)的本地時(shí)間;
datetime.utcnow():返回一個(gè)當(dāng)前utc時(shí)間的datetime對(duì)象;#格林威治時(shí)間
datetime.fromtimestamp(timestamp[, tz]):根據(jù)時(shí)間戮創(chuàng)建一個(gè)datetime對(duì)象,參數(shù)tz指定時(shí)區(qū)信息;
datetime.utcfromtimestamp(timestamp):根據(jù)時(shí)間戮創(chuàng)建一個(gè)datetime對(duì)象;
datetime.combine(date, time):根據(jù)date和time,創(chuàng)建一個(gè)datetime對(duì)象;
datetime.strptime(date_string, format):將格式字符串轉(zhuǎn)換為datetime對(duì)象;
復(fù)制代碼
復(fù)制代碼

 

output

 

方法和屬性

復(fù)制代碼
復(fù)制代碼
dt=datetime.now()#datetime對(duì)象
dt.year、month、day、hour、minute、second、microsecond、tzinfo:
dt.date():獲取date對(duì)象;
dt.time():獲取time對(duì)象;
dt. replace ([ year[ , month[ , day[ , hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ] ] ] ]):
dt. timetuple ()
dt. utctimetuple ()
dt. toordinal ()
dt. weekday ()
dt. isocalendar ()
dt. isoformat ([ sep] )
dt. ctime ():返回一個(gè)日期時(shí)間的C格式字符串,等效于time.ctime(time.mktime(dt.timetuple()));
dt. strftime (format)
復(fù)制代碼
復(fù)制代碼

4.timedelta類,時(shí)間加減

使用timedelta可以很方便的在日期上做天days,小時(shí)hour,分鐘,秒,毫秒,微妙的時(shí)間計(jì)算,如果要計(jì)算月份則需要另外的辦法。

復(fù)制代碼
復(fù)制代碼
#coding:utf-8
from  datetime import *

dt = datetime.now() #日期減一天 dt1 = dt + timedelta(days=-1)#昨天 dt2 = dt - timedelta(days=1)#昨天 dt3 = dt + timedelta(days=1)#明天 delta_obj = dt3-dt print type(delta_obj),delta_obj#<type 'datetime.timedelta'> 1 day, 0:00:00 print delta_obj.days ,delta_obj.total_seconds()#1 86400.0

復(fù)制代碼
復(fù)制代碼

 5、tzinfo時(shí)區(qū)類

復(fù)制代碼
#! /usr/bin/python
# coding=utf-8

from datetime import datetime, tzinfo,timedelta

<> tzinfo是關(guān)于時(shí)區(qū)信息的類 tzinfo是一個(gè)抽象類,所以不能直接被實(shí)例化 > class UTC(tzinfo): <>UTC> def init(self,offset = 0): self._offset = offset

  1. <span style="color: #0000ff">def<span style="color: #000000"> utcoffset(self, dt):
  2. <span style="color: #0000ff">return timedelta(hours=<span style="color: #000000">self._offset)
  3. <span style="color: #0000ff">def<span style="color: #000000"> tzname(self, dt):
  4. <span style="color: #0000ff">return <span style="color: #800000">"<span style="color: #800000">UTC +%s<span style="color: #800000">" %<span style="color: #000000"> self._offset
  5. <span style="color: #0000ff">def<span style="color: #000000"> dst(self, dt):
  6. <span style="color: #0000ff">return timedelta(hours=<span style="color: #000000">self._offset)

#北京時(shí)間 beijing = datetime(2011,11,11,0,0,0,tzinfo = UTC(8)) print "beijing time:",beijing #曼谷時(shí)間 bangkok = datetime(2011,11,11,0,0,0,tzinfo = UTC(7)) print "bangkok time",bangkok #北京時(shí)間轉(zhuǎn)成曼谷時(shí)間 print "beijing-time to bangkok-time:",beijing.astimezone(UTC(7))

#計(jì)算時(shí)間差時(shí)也會(huì)考慮時(shí)區(qū)的問(wèn)題 timespan = beijing - bangkok print "時(shí)差:",timespan

#Output================== # beijing time: 2011-11-11 00:00:00+08:00 # bangkok time 2011-11-11 00:00:00+07:00 # beijing-time to bangkok-time: 2011-11-10 23:00:00+07:00 # 時(shí)差: -1 day, 23:00:00

hashlib加密

hashlib主要提供字符加密功能,將md5和sha模塊整合到了一起,支持md5,sha1, sha224, sha256, sha384, sha512等算法

具體應(yīng)用

復(fù)制代碼
復(fù)制代碼
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#pyversion:python3.5 #owner:fuzj 

import hashlib

# ######## md5 ######## string = "beyongjie"

md5 = hashlib.md5() md5.update(string.encode('utf-8')) #注意轉(zhuǎn)碼 res = md5.hexdigest() print("md5加密結(jié)果:",res)

# ######## sha1 ######## sha1 = hashlib.sha1() sha1.update(string.encode('utf-8')) res = sha1.hexdigest() print("sha1加密結(jié)果:",res)

# ######## sha256 ######## sha256 = hashlib.sha256() sha256.update(string.encode('utf-8')) res = sha256.hexdigest() print("sha256加密結(jié)果:",res)

# ######## sha384 ######## sha384 = hashlib.sha384() sha384.update(string.encode('utf-8')) res = sha384.hexdigest() print("sha384加密結(jié)果:",res)

# ######## sha512 ######## sha512= hashlib.sha512() sha512.update(string.encode('utf-8')) res = sha512.hexdigest() print("sha512加密結(jié)果:",res)

復(fù)制代碼
復(fù)制代碼

 

輸出結(jié)果:

復(fù)制代碼
復(fù)制代碼
md5加密結(jié)果: 0e725e477851ff4076f774dc312d4748
sha1加密結(jié)果: 458d32be8ea38b66300174970ab0a8c0b734252f
sha256加密結(jié)果: 1e62b55bfd02977943f885f6a0998af7cc9cfb95c8ac4a9f30ecccb7c05ec9f4
sha384加密結(jié)果: e91cdf0d2570de5c96ee84e8a12cddf16508685e7a03b3e811099cfcd54b7f52183e20197cff7c07f312157f0ba4875b
sha512加密結(jié)果: 3f0020a726e9c1cb5d22290c967f3dd1bcecb409a51a8088db520750c876aaec3f17a70d7981cd575ed4b89471f743f3f24a146a39d59f215ae3e208d0170073
復(fù)制代碼
復(fù)制代碼

 

注意:hashlib 加密啊的字符串類型為二進(jìn)制編碼,直接加密字符串會(huì)報(bào)如下錯(cuò)誤:

復(fù)制代碼
復(fù)制代碼
sha1 = hashlib.sha1()
sha1.update(string)
res = sha1.hexdigest()
print("sha1加密結(jié)果:",res) 

TypeError: Unicode-objects must be encoded before hashing

復(fù)制代碼
復(fù)制代碼

 

可以使用encode進(jìn)行轉(zhuǎn)換

shaa1 = hashlib.sha1()
shaa1.update(string.encode('utf-8'))
res = shaa1.hexdigest() print("sha1采用encode轉(zhuǎn)換加密結(jié)果:",res)

 

或者使用byte轉(zhuǎn)換為二進(jìn)制

shab1 = hashlib.sha1()
shab1.update(bytes(string,encoding='utf-8'))
res = shab1.hexdigest() print("sha1采用byte轉(zhuǎn)換的結(jié)果:",res)

 

以上輸出:

sha1采用encode轉(zhuǎn)換加密結(jié)果: 458d32be8ea38b66300174970ab0a8c0b734252f
sha1采用byte轉(zhuǎn)換的結(jié)果: 458d32be8ea38b66300174970ab0a8c0b734252f

 

常用方法

  • hash.update(arg) 更新哈希對(duì)象以字符串參數(shù), 注意:如果同一個(gè)hash對(duì)象重復(fù)調(diào)用該方法,則m.update(a); m.update(b) 等效于 m.update(a+b),看下面例子
復(fù)制代碼
復(fù)制代碼
m = hashlib.md5()
m.update('a'.encode('utf-8')) res = m.hexdigest() print("第一次a加密:",res) 

m.update('b'.encode('utf-8')) res = m.hexdigest() print("第二次b加密:",res)

m1 = hashlib.md5() m1.update('b'.encode('utf-8')) res = m1.hexdigest() print("b單獨(dú)加密:",res)

m2 = hashlib.md5() m2.update('ab'.encode('utf-8')) res = m2.hexdigest() print("ab單獨(dú)加密:",res)

輸出結(jié)果: 第一次a加密: 0cc175b9c0f1b6a831c399e269772661 第二次b加密: 187ef4436122d1cc2f40dc2b92f0eba0 b單獨(dú)加密: 92eb5ffee6ae2fec3ad71c777531578f ab單獨(dú)加密: 187ef4436122d1cc2f40dc2b92f0eba0

復(fù)制代碼
復(fù)制代碼

 

  • hash.digest() 返回摘要,作為二進(jìn)制數(shù)據(jù)字符串值,

  • hash.hexdigest() 返回摘要,作為十六進(jìn)制數(shù)據(jù)字符串值,

  • hash.copy() 復(fù)制

高級(jí)加密

以上加密算法雖然依然非常厲害,但時(shí)候存在缺陷,即:通過(guò)撞庫(kù)可以反解。所以,有必要對(duì)加密算法中添加自定義key再來(lái)做加密。

復(fù)制代碼
復(fù)制代碼
low = hashlib.md5()
low.update('ab'.encode('utf-8')) res = low.hexdigest() print("普通加密:",res) 

high = hashlib.md5(b'beyondjie') high.update('ab'.encode('utf-8')) res = high.hexdigest() print("采用key加密:",res)

輸出結(jié)果: 普通加密: 187ef4436122d1cc2f40dc2b92f0eba0 采用key加密: 1b073f6b8cffe609751e4c98537b7653

復(fù)制代碼
復(fù)制代碼

 

附加HMAC-SHA1各語(yǔ)言版本實(shí)現(xiàn)

復(fù)制代碼
在各大開(kāi)放平臺(tái)大行其道的互聯(lián)網(wǎng)開(kāi)發(fā)潮流中,調(diào)用各平臺(tái)的API接口過(guò)程中,無(wú)一例外都會(huì)用到計(jì)算簽名值(sig值)。而在各種計(jì)算簽名的方法中,經(jīng)常被采用的就是HMAC-SHA1,現(xiàn)對(duì)HMAC-SHA1做一個(gè)簡(jiǎn)單的介紹:
  1. HMAC,散列消息鑒別碼,基于密鑰的Hash算法認(rèn)證協(xié)議。實(shí)現(xiàn)原理為:利用已經(jīng)公開(kāi)的Hash函數(shù)和私有的密鑰,來(lái)生成固定長(zhǎng)度的消息鑒別碼;
  2. SHA1、MD5等Hash算法是比較常用的不可逆Hash簽名計(jì)算方法;
  3. BASE64,將任意序列的8字節(jié)字符轉(zhuǎn)換為人眼無(wú)法直接識(shí)別的符號(hào)編碼的一種方法;
  4. 各個(gè)語(yǔ)言版本的實(shí)現(xiàn)為:
  5. Python版:
  6. <span style="color: #0000ff">import<span style="color: #000000"> hmac
  7. <span style="color: #0000ff">import<span style="color: #000000"> hashlib
  8. <span style="color: #0000ff">import<span style="color: #000000"> base64
  9. hmac.new(Token,data,hashlib.sha1).digest().encode(<span style="color: #800000">'<span style="color: #800000">base64<span style="color: #800000">'<span style="color: #000000">).rstrip()

Token:即接口的key

data:要加密的數(shù)據(jù)

  1. PHP版:
  2. base64_encode(hash_hmac(<span style="color: #800000">"<span style="color: #800000">SHA1<span style="color: #800000">"<span style="color: #000000">,clientStr,Token , true))
  3. C++<span style="color: #000000">版(Openssl):
  4. HMAC( EVP_sha1(),
  5. /*key data*/<span style="color: #000000"> strKey.data(),
  6. /*key len*/<span style="color: #000000"> strKey.size(),
  7. /*data */(unsigned char*<span style="color: #000000">) strRandom.data(),
  8. /*data len*/ strRandom.size(), digest, &amp;<span style="color: #000000">digest_len))
  9. Shell版:
  10. echo -n <span style="color: #800000">'<span style="color: #800000">3f88a95c532bea70<span style="color: #800000">' | openssl dgst -hmac <span style="color: #800000">'<span style="color: #800000">123<span style="color: #800000">' -sha1 -binary | base64<br><br><br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>

1 logging模塊簡(jiǎn)介

 
   

logging模塊是Python內(nèi)置的標(biāo)準(zhǔn)模塊,主要用于輸出運(yùn)行日志,可以設(shè)置輸出日志的等級(jí)、日志保存路徑、日志文件回滾等;相比print,具備如下優(yōu)點(diǎn):

 
   
  1. 可以通過(guò)設(shè)置不同的日志等級(jí),在release版本中只輸出重要信息,而不必顯示大量的調(diào)試信息;
  2. print將所有信息都輸出到標(biāo)準(zhǔn)輸出中,嚴(yán)重影響開(kāi)發(fā)者從標(biāo)準(zhǔn)輸出中查看其它數(shù)據(jù);logging則可以由開(kāi)發(fā)者決定將信息輸出到什么地方,以及怎么輸出;
 
   

2 logging模塊使用

 
   

2.1 基本使用

 
   

配置logging基本的設(shè)置,然后在控制臺(tái)輸出日志,

 
   
復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
import logging
logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") logger.info("Finish")

復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
 
   

運(yùn)行時(shí),控制臺(tái)輸出,

 
   
2016-10-09 19:11:19,434 - __main__ - INFO - Start print log 2016-10-09 19:11:19,434 - __main__ - WARNING - Something maybe fail. 2016-10-09 19:11:19,434 - __main__ - INFO - Finish
 
   

logging中可以選擇很多消息級(jí)別,如debug、info、warning、error以及critical。通過(guò)賦予logger或者h(yuǎn)andler不同的級(jí)別,開(kāi)發(fā)者就可以只輸出錯(cuò)誤信息到特定的記錄文件,或者在調(diào)試時(shí)只記錄調(diào)試信息。

 
   

例如,我們將logger的級(jí)別改為DEBUG,再觀察一下輸出結(jié)果,

 
   
logging.basicConfig(level = logging.DEBUG,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
 
   

控制臺(tái)輸出,可以發(fā)現(xiàn),輸出了debug的信息。

 
   
2016-10-09 19:12:08,289 - __main__ - INFO - Start print log 2016-10-09 19:12:08,289 - __main__ - DEBUG - Do something 2016-10-09 19:12:08,289 - __main__ - WARNING - Something maybe fail. 2016-10-09 19:12:08,289 - __main__ - INFO - Finish
 
   

logging.basicConfig函數(shù)各參數(shù):

 
   

filename:指定日志文件名;

 
   

filemode:和file函數(shù)意義相同,指定日志文件的打開(kāi)模式,'w'或者'a';

 
   

format:指定輸出的格式和內(nèi)容,format可以輸出很多有用的信息,

 
   
參數(shù):作用

%(levelno)s:打印日志級(jí)別的數(shù)值 %(levelname)s:打印日志級(jí)別的名稱 %(pathname)s:打印當(dāng)前執(zhí)行程序的路徑,其實(shí)就是sys.argv[0] %(filename)s:打印當(dāng)前執(zhí)行程序名 %(funcName)s:打印日志的當(dāng)前函數(shù) %(lineno)d:打印日志的當(dāng)前行號(hào) %(asctime)s:打印日志的時(shí)間 %(thread)d:打印線程ID %(threadName)s:打印線程名稱 %(process)d:打印進(jìn)程ID %(message)s:打印日志信息

 
   

datefmt:指定時(shí)間格式,同time.strftime();

 
   

level:設(shè)置日志級(jí)別,默認(rèn)為logging.WARNNING;

 
   

stream:指定將日志的輸出流,可以指定輸出到sys.stderr,sys.stdout或者文件,默認(rèn)輸出到sys.stderr,當(dāng)stream和filename同時(shí)指定時(shí),stream被忽略;

 
   

2.2 將日志寫(xiě)入到文件

 
   

2.2.1 將日志寫(xiě)入到文件

 
   

設(shè)置logging,創(chuàng)建一個(gè)FileHandler,并對(duì)輸出消息的格式進(jìn)行設(shè)置,將其添加到logger,然后將日志寫(xiě)入到指定的文件中,

 
   
復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
import logging
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)

logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") logger.info("Finish")

復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
 
   

log.txt中日志數(shù)據(jù)為,

 
   
2016-10-09 19:01:13,263 - __main__ - INFO - Start print log 2016-10-09 19:01:13,263 - __main__ - WARNING - Something maybe fail. 2016-10-09 19:01:13,263 - __main__ - INFO - Finish
 
   

2.2.2 將日志同時(shí)輸出到屏幕和日志文件

 
   

logger中添加StreamHandler,可以將日志輸出到屏幕上,

 
   
復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
import logging
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

console = logging.StreamHandler() console.setLevel(logging.INFO)

logger.addHandler(handler) logger.addHandler(console)

logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") logger.info("Finish")

復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
 
   

可以在log.txt文件和控制臺(tái)中看到,

 
   
2016-10-09 19:20:46,553 - __main__ - INFO - Start print log 2016-10-09 19:20:46,553 - __main__ - WARNING - Something maybe fail. 2016-10-09 19:20:46,553 - __main__ - INFO - Finish
 
   

可以發(fā)現(xiàn),logging有一個(gè)日志處理的主對(duì)象,其他處理方式都是通過(guò)addHandler添加進(jìn)去,logging中包含的handler主要有如下幾種,

 
   
handler名稱:位置;作用

StreamHandler:logging.StreamHandler;日志輸出到流,可以是sys.stderr,sys.stdout或者文件 FileHandler:logging.FileHandler;日志輸出到文件 BaseRotatingHandler:logging.handlers.BaseRotatingHandler;基本的日志回滾方式 RotatingHandler:logging.handlers.RotatingHandler;日志回滾方式,支持日志文件最大數(shù)量和日志文件回滾 TimeRotatingHandler:logging.handlers.TimeRotatingHandler;日志回滾方式,在一定時(shí)間區(qū)域內(nèi)回滾日志文件 SocketHandler:logging.handlers.SocketHandler;遠(yuǎn)程輸出日志到TCP/IP sockets DatagramHandler:logging.handlers.DatagramHandler;遠(yuǎn)程輸出日志到UDP sockets SMTPHandler:logging.handlers.SMTPHandler;遠(yuǎn)程輸出日志到郵件地址 SysLogHandler:logging.handlers.SysLogHandler;日志輸出到syslog NTEventLogHandler:logging.handlers.NTEventLogHandler;遠(yuǎn)程輸出日志到Windows NT/2000/XP的事件日志 MemoryHandler:logging.handlers.MemoryHandler;日志輸出到內(nèi)存中的指定buffer HTTPHandler:logging.handlers.HTTPHandler;通過(guò)"GET"或者"POST"遠(yuǎn)程輸出到HTTP服務(wù)器

 
   

2.2.3 日志回滾

 
   

使用RotatingFileHandler,可以實(shí)現(xiàn)日志回滾,

 
   
復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
import logging
from logging.handlers import RotatingFileHandler
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
#定義一個(gè)RotatingFileHandler,最多備份3個(gè)日志文件,每個(gè)日志文件最大1K
rHandler = RotatingFileHandler("log.txt",maxBytes = 1*1024,backupCount = 3)
rHandler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
rHandler.setFormatter(formatter)

console = logging.StreamHandler() console.setLevel(logging.INFO) console.setFormatter(formatter)

logger.addHandler(rHandler) logger.addHandler(console)

logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") logger.info("Finish")

復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
 
   

可以在工程目錄中看到,備份的日志文件,

 
   
2016/10/09  19:36 732 log.txt 2016/10/09 19:36 967 log.txt.1 2016/10/09 19:36 985 log.txt.2 2016/10/09 19:36 976 log.txt.3
 
   

2.3 設(shè)置消息的等級(jí)

 
   

可以設(shè)置不同的日志等級(jí),用于控制日志的輸出,

 
   
日志等級(jí):使用范圍

FATAL:致命錯(cuò)誤 CRITICAL:特別糟糕的事情,如內(nèi)存耗盡、磁盤(pán)空間為空,一般很少使用 ERROR:發(fā)生錯(cuò)誤時(shí),如IO操作失敗或者連接問(wèn)題 WARNING:發(fā)生很重要的事件,但是并不是錯(cuò)誤時(shí),如用戶登錄密碼錯(cuò)誤 INFO:處理請(qǐng)求或者狀態(tài)變化等日常事務(wù) DEBUG:調(diào)試過(guò)程中使用DEBUG等級(jí),如算法中每個(gè)循環(huán)的中間狀態(tài)

 
   

2.4 捕獲traceback

 
   

Python中的traceback模塊被用于跟蹤異常返回信息,可以在logging中記錄下traceback,

 
   

代碼,

 
   
復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
import logging
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

console = logging.StreamHandler() console.setLevel(logging.INFO)

logger.addHandler(handler) logger.addHandler(console)

logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") try: open("sklearn.txt","rb") except (SystemExit,KeyboardInterrupt): raise except Exception: logger.error("Faild to open sklearn.txt from logger.error",exc_info = True)

logger.info("Finish")

復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
 
   

控制臺(tái)和日志文件log.txt中輸出,

 
   
  1. Start print log
  2. Something maybe fail.
  3. Faild to open sklearn.txt from logger.error Traceback (most recent call last): File "G:\zhb7627\Code\Eclipse WorkSpace\PythonTest\test.py", line 23, in <module> open("sklearn.txt","rb") IOError: [Errno 2] No such file or directory: 'sklearn.txt' Finish
 
   

也可以使用logger.exception(msg,_args),它等價(jià)于logger.error(msg,exc_info = True,_args),

 
   

 
   
logger.error("Faild to open sklearn.txt from logger.error",exc_info = True)
 
   

替換為,

 
   
logger.exception("Failed to open sklearn.txt from logger.exception")
 
   

控制臺(tái)和日志文件log.txt中輸出,

 
   
  1. Start print log
  2. Something maybe fail.
  3. Failed to open sklearn.txt from logger.exception Traceback (most recent call last): File "G:\zhb7627\Code\Eclipse WorkSpace\PythonTest\test.py", line 23, in <module> open("sklearn.txt","rb") IOError: [Errno 2] No such file or directory: 'sklearn.txt' Finish
 
   

2.5 多模塊使用logging

 
   

主模塊mainModule.py,

 
   
復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
import logging
import subModule
logger = logging.getLogger("mainModule")
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

console = logging.StreamHandler() console.setLevel(logging.INFO) console.setFormatter(formatter)

logger.addHandler(handler) logger.addHandler(console)

logger.info("creating an instance of subModule.subModuleClass") a = subModule.SubModuleClass() logger.info("calling subModule.subModuleClass.doSomething") a.doSomething() logger.info("done with subModule.subModuleClass.doSomething") logger.info("calling subModule.some_function") subModule.som_function() logger.info("done with subModule.some_function")

復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
 
   

子模塊subModule.py,

 
   
復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
import logging

module_logger = logging.getLogger("mainModule.sub") class SubModuleClass(object): def init(self): self.logger = logging.getLogger("mainModule.sub.module") self.logger.info("creating an instance in SubModuleClass") def doSomething(self): self.logger.info("do something in SubModule") a = [] a.append(1) self.logger.debug("list a = " + str(a)) self.logger.info("finish something in SubModuleClass")

def som_function(): module_logger.info("call function some_function")

復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
 
   

執(zhí)行之后,在控制和日志文件log.txt中輸出,

 
   
2016-10-09 20:25:42,276 - mainModule - INFO - creating an instance of subModule.subModuleClass 2016-10-09 20:25:42,279 - mainModule.sub.module - INFO - creating an instance in SubModuleClass 2016-10-09 20:25:42,279 - mainModule - INFO - calling subModule.subModuleClass.doSomething 2016-10-09 20:25:42,279 - mainModule.sub.module - INFO - do something in SubModule 2016-10-09 20:25:42,279 - mainModule.sub.module - INFO - finish something in SubModuleClass 2016-10-09 20:25:42,279 - mainModule - INFO - done with subModule.subModuleClass.doSomething 2016-10-09 20:25:42,279 - mainModule - INFO - calling subModule.some_function 2016-10-09 20:25:42,279 - mainModule.sub - INFO - call function some_function 2016-10-09 20:25:42,279 - mainModule - INFO - done with subModule.some_function
 
   

首先在主模塊定義了logger'mainModule',并對(duì)它進(jìn)行了配置,就可以在解釋器進(jìn)程里面的其他地方通過(guò)getLogger('mainModule')得到的對(duì)象都是一樣的,不需要重新配置,可以直接使用。定義的該logger的子logger,都可以共享父logger的定義和配置,所謂的父子logger是通過(guò)命名來(lái)識(shí)別,任意以'mainModule'開(kāi)頭的logger都是它的子logger,例如'mainModule.sub'。

 
   

實(shí)際開(kāi)發(fā)一個(gè)application,首先可以通過(guò)logging配置文件編寫(xiě)好這個(gè)application所對(duì)應(yīng)的配置,可以生成一個(gè)根logger,如'PythonAPP',然后在主函數(shù)中通過(guò)fileConfig加載logging配置,接著在application的其他地方、不同的模塊中,可以使用根logger的子logger,如'PythonAPP.Core','PythonAPP.Web'來(lái)進(jìn)行l(wèi)og,而不需要反復(fù)的定義和配置各個(gè)模塊的logger。

 
   

3 通過(guò)JSON或者YAML文件配置logging模塊

 
   

盡管可以在Python代碼中配置logging,但是這樣并不夠靈活,最好的方法是使用一個(gè)配置文件來(lái)配置。在Python 2.7及以后的版本中,可以從字典中加載logging配置,也就意味著可以通過(guò)JSON或者YAML文件加載日志的配置。

 
   

3.1 通過(guò)JSON文件配置

 
   

JSON配置文件,

 
   
  1. {
  2. "version":1,
  3. "disable_existing_loggers":false,
  4. "formatters":{ "simple":{ "format":"%(asctime)s - %(name)s - %(levelname)s - %(message)s" } }, "handlers":{ "console":{ "class":"logging.StreamHandler", "level":"DEBUG", "formatter":"simple", "stream":"ext://sys.stdout" }, "info_file_handler":{ "class":"logging.handlers.RotatingFileHandler", "level":"INFO", "formatter":"simple", "filename":"info.log", "maxBytes":"10485760", "backupCount":20, "encoding":"utf8" }, "error_file_handler":{ "class":"logging.handlers.RotatingFileHandler", "level":"ERROR", "formatter":"simple", "filename":"errors.log", "maxBytes":10485760, "backupCount":20, "encoding":"utf8" } }, "loggers":{ "my_module":{ "level":"ERROR", "handlers":["info_file_handler"], "propagate":"no" } }, "root":{ "level":"INFO", "handlers":["console","info_file_handler","error_file_handler"] } }
 
   

通過(guò)JSON加載配置文件,然后通過(guò)logging.dictConfig配置logging,

 
   
復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
import json
import logging.config
import os

def setup_logging(default_path = "logging.json",default_level = logging.INFO,env_key = "LOG_CFG"): path = default_path value = os.getenv(env_key,None) if value: path = value if os.path.exists(path): with open(path,"r") as f: config = json.load(f) logging.config.dictConfig(config) else: logging.basicConfig(level = default_level)

def func(): logging.info("start func")

  1. logging.info("exec func")
  2. logging.info("end func")

if name == "main": setup_logging(default_path = "logging.json") func()

復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
 
   

3.2 通過(guò)YAML文件配置

 
   

通過(guò)YAML文件進(jìn)行配置,比JSON看起來(lái)更加簡(jiǎn)介明了,

 
   
  1. version: 1
  2. disable_existing_loggers: False
  3. formatters: simple: format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s" handlers: console: class: logging.StreamHandler level: DEBUG formatter: simple stream: ext://sys.stdout info_file_handler: class: logging.handlers.RotatingFileHandler level: INFO formatter: simple filename: info.log maxBytes: 10485760 backupCount: 20 encoding: utf8 error_file_handler: class: logging.handlers.RotatingFileHandler level: ERROR formatter: simple filename: errors.log maxBytes: 10485760 backupCount: 20 encoding: utf8 loggers: my_module: level: ERROR handlers: [info_file_handler] propagate: no root: level: INFO handlers: [console,info_file_handler,error_file_handler]
 
   

通過(guò)YAML加載配置文件,然后通過(guò)logging.dictConfig配置logging,

 
   
復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
import yaml
import logging.config
import os

def setup_logging(default_path = "logging.yaml",default_level = logging.INFO,env_key = "LOG_CFG"): path = default_path value = os.getenv(env_key,None) if value: path = value if os.path.exists(path): with open(path,"r") as f: config = yaml.load(f) logging.config.dictConfig(config) else: logging.basicConfig(level = default_level)

def func(): logging.info("start func")

  1. logging.info("exec func")
  2. logging.info("end func")

if name == "main": setup_logging(default_path = "logging.yaml") func()

復(fù)制代碼
復(fù)制代碼
復(fù)制代碼
 

subprocess模塊

 
   
 
   

subprocess是Python 2.4中新增的一個(gè)模塊,它允許你生成新的進(jìn)程,連接到它們的 input/output/error 管道,并獲取它們的返回(狀態(tài))碼。這個(gè)模塊的目的在于替換幾個(gè)舊的模塊和方法,如:

 
   
  • os.system
  • os.spawn*
 
   

1. subprocess模塊中的常用函數(shù)

 
   
函數(shù)描述
subprocess.run()Python 3.5中新增的函數(shù)。執(zhí)行指定的命令,等待命令執(zhí)行完成后返回一個(gè)包含執(zhí)行結(jié)果的CompletedProcess類的實(shí)例。
subprocess.call()執(zhí)行指定的命令,返回命令執(zhí)行狀態(tài),其功能類似于os.system(cmd)。
subprocess.check_call()Python 2.5中新增的函數(shù)。 執(zhí)行指定的命令,如果執(zhí)行成功則返回狀態(tài)碼,否則拋出異常。其功能等價(jià)于subprocess.run(..., check=True)。
subprocess.check_output()Python 2.7中新增的的函數(shù)。執(zhí)行指定的命令,如果執(zhí)行狀態(tài)碼為0則返回命令執(zhí)行結(jié)果,否則拋出異常。
subprocess.getoutput(cmd)接收字符串格式的命令,執(zhí)行命令并返回執(zhí)行結(jié)果,其功能類似于os.popen(cmd).read()和commands.getoutput(cmd)。
subprocess.getstatusoutput(cmd)執(zhí)行cmd命令,返回一個(gè)元組(命令執(zhí)行狀態(tài), 命令執(zhí)行結(jié)果輸出),其功能類似于commands.getstatusoutput()。
 
   

說(shuō)明:

  1. 在Python 3.5之后的版本中,官方文檔中提倡通過(guò)subprocess.run()函數(shù)替代其他函數(shù)來(lái)使用subproccess模塊的功能;
  2. 在Python 3.5之前的版本中,我們可以通過(guò)subprocess.call(),subprocess.getoutput()等上面列出的其他函數(shù)來(lái)使用subprocess模塊的功能;
  3. subprocess.run()、subprocess.call()、subprocess.check_call()和subprocess.check_output()都是通過(guò)對(duì)subprocess.Popen的封裝來(lái)實(shí)現(xiàn)的高級(jí)函數(shù),因此如果我們需要更復(fù)雜功能時(shí),可以通過(guò)subprocess.Popen來(lái)完成。
  4. subprocess.getoutput()和subprocess.getstatusoutput()函數(shù)是來(lái)自Python 2.x的commands模塊的兩個(gè)遺留函數(shù)。它們隱式的調(diào)用系統(tǒng)shell,并且不保證其他函數(shù)所具有的安全性和異常處理的一致性。另外,它們從Python 3.3.4開(kāi)始才支持Windows平臺(tái)。
 
   

2. 上面各函數(shù)的定義及參數(shù)說(shuō)明

 
   
函數(shù)參數(shù)列表:
 
   
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False, universal_newlines=False) '
運(yùn)行

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)

subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False, timeout=None)

subprocess.getstatusoutput(cmd)

subprocess.getoutput(cmd)

 
   
參數(shù)說(shuō)明:
 
   
  • args: 要執(zhí)行的shell命令,默認(rèn)應(yīng)該是一個(gè)字符串序列,如['df', '-Th']或('df', '-Th'),也可以是一個(gè)字符串,如'df -Th',但是此時(shí)需要把shell參數(shù)的值置為T(mén)rue。
  • shell: 如果shell為T(mén)rue,那么指定的命令將通過(guò)shell執(zhí)行。如果我們需要訪問(wèn)某些shell的特性,如管道、文件名通配符、環(huán)境變量擴(kuò)展功能,這將是非常有用的。當(dāng)然,python本身也提供了許多類似shell的特性的實(shí)現(xiàn),如glob、fnmatch、os.walk()、os.path.expandvars()、os.expanduser()和shutil等。
  • check: 如果check參數(shù)的值是True,且執(zhí)行命令的進(jìn)程以非0狀態(tài)碼退出,則會(huì)拋出一個(gè)CalledProcessError的異常,且該異常對(duì)象會(huì)包含 參數(shù)、退出狀態(tài)碼、以及stdout和stderr(如果它們有被捕獲的話)。
  • stdout, stderr:
  • run()函數(shù)默認(rèn)不會(huì)捕獲命令執(zhí)行結(jié)果的正常輸出和錯(cuò)誤輸出,如果我們向獲取這些內(nèi)容需要傳遞subprocess.PIPE,然后可以通過(guò)返回的CompletedProcess類實(shí)例的stdout和stderr屬性或捕獲相應(yīng)的內(nèi)容;
  • call()和check_call()函數(shù)返回的是命令執(zhí)行的狀態(tài)碼,而不是CompletedProcess類實(shí)例,所以對(duì)于它們而言,stdout和stderr不適合賦值為subprocess.PIPE;
  • check_output()函數(shù)默認(rèn)就會(huì)返回命令執(zhí)行結(jié)果,所以不用設(shè)置stdout的值,如果我們希望在結(jié)果中捕獲錯(cuò)誤信息,可以執(zhí)行stderr=subprocess.STDOUT。
  • input: 該參數(shù)是傳遞給Popen.communicate(),通常該參數(shù)的值必須是一個(gè)字節(jié)序列,如果universal_newlines=True,則其值應(yīng)該是一個(gè)字符串。
  • universal_newlines: 該參數(shù)影響的是輸入與輸出的數(shù)據(jù)格式,比如它的值默認(rèn)為False,此時(shí)stdout和stderr的輸出是字節(jié)序列;當(dāng)該參數(shù)的值設(shè)置為T(mén)rue時(shí),stdout和stderr的輸出是字符串。
 
   

3. subprocess.CompletedProcess類介紹

 
   

需要說(shuō)明的是,subprocess.run()函數(shù)是Python3.5中新增的一個(gè)高級(jí)函數(shù),其返回值是一個(gè)subprocess.CompletedPorcess類的實(shí)例,因此,subprocess.completedPorcess類也是Python 3.5中才存在的。它表示的是一個(gè)已結(jié)束進(jìn)程的狀態(tài)信息,它所包含的屬性如下:

 
   
  • args: 用于加載該進(jìn)程的參數(shù),這可能是一個(gè)列表或一個(gè)字符串
  • returncode: 子進(jìn)程的退出狀態(tài)碼。通常情況下,退出狀態(tài)碼為0則表示進(jìn)程成功運(yùn)行了;一個(gè)負(fù)值-N表示這個(gè)子進(jìn)程被信號(hào)N終止了
  • stdout: 從子進(jìn)程捕獲的stdout。這通常是一個(gè)字節(jié)序列,如果run()函數(shù)被調(diào)用時(shí)指定universal_newlines=True,則該屬性值是一個(gè)字符串。如果run()函數(shù)被調(diào)用時(shí)指定stderr=subprocess.STDOUT,那么stdout和stderr將會(huì)被整合到這一個(gè)屬性中,且stderr將會(huì)為None
  • stderr: 從子進(jìn)程捕獲的stderr。它的值與stdout一樣,是一個(gè)字節(jié)序列或一個(gè)字符串。如果stderr滅有被捕獲的話,它的值就為None
  • check_returncode(): 如果returncode是一個(gè)非0值,則該方法會(huì)拋出一個(gè)CalledProcessError異常。
 
   

4. 實(shí)例

 
   
subprocess.run()
 
   
  1. >>> subprocess.run(["ls", "-l"]) # doesn't capture output
  2. CompletedProcess(args=['ls', '-l'], returncode=0)

>>> subprocess.run("exit 1", shell=True, check=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE) CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0, stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')

 
   
subprocess.call()
 
   
  1. >>> subprocess.call(['ls', '-l'])
  2. 總用量 160
  3. drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的 drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板 drwxr-xr-x 2 wader wader 4096 12月 7 2015 視頻 drwxr-xr-x 2 wader wader 4096 12月 7 2015 圖片 drwxr-xr-x 2 wader wader 4096 12月 7 2015 文檔 drwxr-xr-x 2 wader wader 4096 4月 13 2016 下載 drwxr-xr-x 2 wader wader 4096 12月 7 2015 音樂(lè) drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面 0 >>> subprocess.call('ls -l', shell=True) 總用量 160 drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的 drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板 drwxr-xr-x 2 wader wader 4096 12月 7 2015 視頻 drwxr-xr-x 2 wader wader 4096 12月 7 2015 圖片 drwxr-xr-x 2 wader wader 4096 12月 7 2015 文檔 drwxr-xr-x 2 wader wader 4096 4月 13 2016 下載 drwxr-xr-x 2 wader wader 4096 12月 7 2015 音樂(lè) drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面 0 >>> subprocess.call(['ls', '-l'], stdout=subprocess.DEVNULL) 0 >>> subprocess.call(['ls', '-l', '/test']) ls: 無(wú)法訪問(wèn)/test: 沒(méi)有那個(gè)文件或目錄 2
 
   
suprocess.check_call()
 
   
  1. >>> subprocess.check_call(['ls', '-l'])
  2. 總用量 160
  3. drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的 drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板 drwxr-xr-x 2 wader wader 4096 12月 7 2015 視頻 drwxr-xr-x 2 wader wader 4096 12月 7 2015 圖片 drwxr-xr-x 2 wader wader 4096 12月 7 2015 文檔 drwxr-xr-x 2 wader wader 4096 4月 13 2016 下載 drwxr-xr-x 2 wader wader 4096 12月 7 2015 音樂(lè) drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面 0 >>> subprocess.check_call('ls -l', shell=True) 總用量 160 drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的 drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板 drwxr-xr-x 2 wader wader 4096 12月 7 2015 視頻 drwxr-xr-x 2 wader wader 4096 12月 7 2015 圖片 drwxr-xr-x 2 wader wader 4096 12月 7 2015 文檔 drwxr-xr-x 2 wader wader 4096 4月 13 2016 下載 drwxr-xr-x 2 wader wader 4096 12月 7 2015 音樂(lè) drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面 0 >>> subprocess.check_call('ls -l /test', shell=True) ls: 無(wú)法訪問(wèn)/test: 沒(méi)有那個(gè)文件或目錄 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.4/subprocess.py", line 557, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command 'ls -l /test' returned non-zero exit status 2
 
   
sbuprocess.check_output()
 
   
  1. >>> ret = subprocess.check_output(['ls', '-l'])
  2. >>> print(ret)
  3. b' \xe5\x85\xac\xe5\x85\xb1\xe7\x9a\x84\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe6\xa8\xa1\xe6\x9d\xbf\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe8\xa7\x86\xe9\xa2\x91\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe5\x9b\xbe\xe7\x89\x87\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe6\x96\x87\xe6\xa1\xa3\ndrwxr-xr-x 2 wader wader 4096 4\xe6\x9c\x88 13 2016 \xe4\xb8\x8b\xe8\xbd\xbd\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe9\x9f\xb3\xe4\xb9\x90\ndrwxr-xr-x 7 wader wader 4096 5\xe6\x9c\x88 26 2016 \xe6\xa1\x8c\xe9\x9d\xa2\n' >>> ret = subprocess.check_output(['ls', '-l'], universal_newlines=True) >>> print(ret) 總用量 160 drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的 drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板 drwxr-xr-x 2 wader wader 4096 12月 7 2015 視頻 drwxr-xr-x 2 wader wader 4096 12月 7 2015 圖片 drwxr-xr-x 2 wader wader 4096 12月 7 2015 文檔 drwxr-xr-x 2 wader wader 4096 4月 13 2016 下載 drwxr-xr-x 2 wader wader 4096 12月 7 2015 音樂(lè) drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
 
   
subprocess.getoutput()與subprocess.getstatusoutput()
 
   
  1. >>> ret = subprocess.getoutput('ls -l')
  2. >>> print(ret)
  3. 總用量 160
  4. drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的 drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板 drwxr-xr-x 2 wader wader 4096 12月 7 2015 視頻 drwxr-xr-x 2 wader wader 4096 12月 7 2015 圖片 drwxr-xr-x 2 wader wader 4096 12月 7 2015 文檔 drwxr-xr-x 2 wader wader 4096 4月 13 2016 下載 drwxr-xr-x 2 wader wader 4096 12月 7 2015 音樂(lè) drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面 >>> retcode, output = subprocess.getstatusoutput('ls -l') >>> print(retcode) 0 >>> print(output) 總用量 160 drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的 drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板 drwxr-xr-x 2 wader wader 4096 12月 7 2015 視頻 drwxr-xr-x 2 wader wader 4096 12月 7 2015 圖片 drwxr-xr-x 2 wader wader 4096 12月 7 2015 文檔 drwxr-xr-x 2 wader wader 4096 4月 13 2016 下載 drwxr-xr-x 2 wader wader 4096 12月 7 2015 音樂(lè) drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面 >>> retcode, output = subprocess.getstatusoutput('ls -l /test') >>> print(retcode) 2 >>> print(output) ls: 無(wú)法訪問(wèn)/test: 沒(méi)有那個(gè)文件或目錄
 
   

三、subprocess.Popen介紹

 
   
 
   

該類用于在一個(gè)新的進(jìn)程中執(zhí)行一個(gè)子程序。前面我們提到過(guò),上面介紹的這些函數(shù)都是基于subprocess.Popen類實(shí)現(xiàn)的,通過(guò)使用這些被封裝后的高級(jí)函數(shù)可以很方面的完成一些常見(jiàn)的需求。由于subprocess模塊底層的進(jìn)程創(chuàng)建和管理是由Popen類來(lái)處理的,因此,當(dāng)我們無(wú)法通過(guò)上面哪些高級(jí)函數(shù)來(lái)實(shí)現(xiàn)一些不太常見(jiàn)的功能時(shí)就可以通過(guò)subprocess.Popen類提供的靈活的api來(lái)完成。

 
   

1.subprocess.Popen的構(gòu)造函數(shù)

 
   
class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, startup_info=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=())
 
   

參數(shù)說(shuō)明:

 
   
  • args: 要執(zhí)行的shell命令,可以是字符串,也可以是命令各個(gè)參數(shù)組成的序列。當(dāng)該參數(shù)的值是一個(gè)字符串時(shí),該命令的解釋過(guò)程是與平臺(tái)相關(guān)的,因此通常建議將args參數(shù)作為一個(gè)序列傳遞。
  • bufsize: 指定緩存策略,0表示不緩沖,1表示行緩沖,其他大于1的數(shù)字表示緩沖區(qū)大小,負(fù)數(shù) 表示使用系統(tǒng)默認(rèn)緩沖策略。
  • stdin, stdout, stderr: 分別表示程序標(biāo)準(zhǔn)輸入、輸出、錯(cuò)誤句柄。
  • preexec_fn: 用于指定一個(gè)將在子進(jìn)程運(yùn)行之前被調(diào)用的可執(zhí)行對(duì)象,只在Unix平臺(tái)下有效。
  • close_fds: 如果該參數(shù)的值為T(mén)rue,則除了0,1和2之外的所有文件描述符都將會(huì)在子進(jìn)程執(zhí)行之前被關(guān)閉。
  • shell: 該參數(shù)用于標(biāo)識(shí)是否使用shell作為要執(zhí)行的程序,如果shell值為T(mén)rue,則建議將args參數(shù)作為一個(gè)字符串傳遞而不要作為一個(gè)序列傳遞。
  • cwd: 如果該參數(shù)值不是None,則該函數(shù)將會(huì)在執(zhí)行這個(gè)子進(jìn)程之前改變當(dāng)前工作目錄。
  • env: 用于指定子進(jìn)程的環(huán)境變量,如果env=None,那么子進(jìn)程的環(huán)境變量將從父進(jìn)程中繼承。如果env!=None,它的值必須是一個(gè)映射對(duì)象。
  • universal_newlines: 如果該參數(shù)值為T(mén)rue,則該文件對(duì)象的stdin,stdout和stderr將會(huì)作為文本流被打開(kāi),否則他們將會(huì)被作為二進(jìn)制流被打開(kāi)。
  • startupinfo和creationflags: 這兩個(gè)參數(shù)只在Windows下有效,它們將被傳遞給底層的CreateProcess()函數(shù),用于設(shè)置子進(jìn)程的一些屬性,如主窗口的外觀,進(jìn)程優(yōu)先級(jí)等。
 
   

2. subprocess.Popen類的實(shí)例可調(diào)用的方法

 
   
方法描述
Popen.poll()用于檢查子進(jìn)程(命令)是否已經(jīng)執(zhí)行結(jié)束,沒(méi)結(jié)束返回None,結(jié)束后返回狀態(tài)碼。
Popen.wait(timeout=None)等待子進(jìn)程結(jié)束,并返回狀態(tài)碼;如果在timeout指定的秒數(shù)之后進(jìn)程還沒(méi)有結(jié)束,將會(huì)拋出一個(gè)TimeoutExpired異常。
Popen.communicate(input=None, timeout=None)該方法可用來(lái)與進(jìn)程進(jìn)行交互,比如發(fā)送數(shù)據(jù)到stdin,從stdout和stderr讀取數(shù)據(jù),直到到達(dá)文件末尾。
Popen.send_signal(signal)發(fā)送指定的信號(hào)給這個(gè)子進(jìn)程。
Popen.terminate()停止該子進(jìn)程。
Popen.kill()殺死該子進(jìn)程。
 
   
關(guān)于communicate()方法的說(shuō)明:
 
   
  • 該方法中的可選參數(shù) input 應(yīng)該是將被發(fā)送給子進(jìn)程的數(shù)據(jù),或者如沒(méi)有數(shù)據(jù)發(fā)送給子進(jìn)程,該參數(shù)應(yīng)該是None。input參數(shù)的數(shù)據(jù)類型必須是字節(jié)串,如果universal_newlines參數(shù)值為T(mén)rue,則input參數(shù)的數(shù)據(jù)類型必須是字符串。
  • 該方法返回一個(gè)元組(stdout_data, stderr_data),這些數(shù)據(jù)將會(huì)是字節(jié)穿或字符串(如果universal_newlines的值為T(mén)rue)。
  • 如果在timeout指定的秒數(shù)后該進(jìn)程還沒(méi)有結(jié)束,將會(huì)拋出一個(gè)TimeoutExpired異常。捕獲這個(gè)異常,然后重新嘗試通信不會(huì)丟失任何輸出的數(shù)據(jù)。但是超時(shí)之后子進(jìn)程并沒(méi)有被殺死,為了合理的清除相應(yīng)的內(nèi)容,一個(gè)好的應(yīng)用應(yīng)該手動(dòng)殺死這個(gè)子進(jìn)程來(lái)結(jié)束通信。
  • 需要注意的是,這里讀取的數(shù)據(jù)是緩沖在內(nèi)存中的,所以,如果數(shù)據(jù)大小非常大或者是無(wú)限的,就不應(yīng)該使用這個(gè)方法。
 
   

3. subprocess.Popen使用實(shí)例

 
   
實(shí)例1:
 
   
  1. >>> import subprocess
  2. >>>
  3. >>> p = subprocess.Popen('df -Th', stdout=subprocess.PIPE, shell=True)
  4. >>> print(p.stdout.read())
  5. Filesystem Type Size Used Avail Use% Mounted on /dev/vda1 ext4 40G 12G 26G 31% / devtmpfs devtmpfs 3.9G 0 3.9G 0% /dev tmpfs tmpfs 3.9G 0 3.9G 0% /dev/shm tmpfs tmpfs 3.9G 386M 3.5G 10% /run tmpfs tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup tmpfs tmpfs 783M 0 783M 0% /run/user/0 tmpfs tmpfs 783M 0 783M 0% /run/user/1000
 
   
實(shí)例2:
 
   
  1. >>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  2. >>> obj.stdin.write('print(1) \n')
  3. >>> obj.stdin.write('print(2) \n') >>> obj.stdin.write('print(3) \n') >>> out,err = obj.communicate() >>> print(out) 1 2 3

>>> print(err)

 
   
實(shí)例3:
 
   
  1. >>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  2. >>> out,err = obj.communicate(input='print(1) \n')
  3. >>> print(out) 1

>>> print(err)

 
   
實(shí)例4:
 
   

實(shí)現(xiàn)類似df -Th | grep data命令的功能,實(shí)際上就是實(shí)現(xiàn)shell中管道的共功能。

 
   
  1. >>>
  2. >>> p1 = subprocess.Popen(['df', '-Th'], stdout=subprocess.PIPE)
  3. >>> p2 = subprocess.Popen(['grep', 'data'], stdin=p1.stdout, stdout=subprocess.PIPE) >>> out,err = p2.communicate() >>> print(out) /dev/vdb1 ext4 493G 4.8G 463G 2% /data /dev/vdd1 ext4 1008G 420G 537G 44% /data1 /dev/vde1 ext4 985G 503G 432G 54% /data2

>>> print(err) None

 
   

四、總結(jié)

 
   
 
   

那么我們到底該用哪個(gè)模塊、哪個(gè)函數(shù)來(lái)執(zhí)行命令與系統(tǒng)及系統(tǒng)進(jìn)行交互呢?下面我們來(lái)做個(gè)總結(jié):

 
   
  • 首先應(yīng)該知道的是,Python2.4版本引入了subprocess模塊用來(lái)替換os.system()、os.popen()、os.spawn*()等函數(shù)以及commands模塊;也就是說(shuō)如果你使用的是Python 2.4及以上的版本就應(yīng)該使用subprocess模塊了。
  • 如果你的應(yīng)用使用的Python 2.4以上,但是是Python 3.5以下的版本,Python官方給出的建議是使用subprocess.call()函數(shù)。Python 2.5中新增了一個(gè)subprocess.check_call()函數(shù),Python 2.7中新增了一個(gè)subprocess.check_output()函數(shù),這兩個(gè)函數(shù)也可以按照需求進(jìn)行使用。
  • 如果你的應(yīng)用使用的是Python 3.5及以上的版本(目前應(yīng)該還很少),Python官方給出的建議是盡量使用subprocess.run()函數(shù)。
  • 當(dāng)subprocess.call()、subprocess.check_call()、subprocess.check_output()和subprocess.run()這些高級(jí)函數(shù)無(wú)法滿足需求時(shí),我們可以使用subprocess.Popen類來(lái)實(shí)現(xiàn)我們需要的復(fù)雜功能。
 
   

json ,pickle模塊

 
   

JSON(JavaScript Object Notation, JS 對(duì)象標(biāo)記) 是一種輕量級(jí)的數(shù)據(jù)交換格式。JSON的數(shù)據(jù)格式其實(shí)就是python里面的字典格式,里面可以包含方括號(hào)括起來(lái)的數(shù)組,也就是python里面的列表。

在python中,有專門(mén)處理json格式的模塊—— json 和 picle模塊

  Json   模塊提供了四個(gè)方法: dumps、dump、loads、load

pickle 模塊也提供了四個(gè)功能:dumps、dump、loads、load
一. dumps 和 dump:
 dumps和dump   序列化方法
       dumps只完成了序列化為str,
       dump必須傳文件描述符,將序列化的str保存到文件中
查看源碼:
def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
        allow_nan=True, cls=None, indent=None, separators=None,
        default=None, sort_keys=False, **kw):
    # Serialize ``obj`` to a JSON formatted ``str``. # 序列號(hào) “obj” 數(shù)據(jù)類型 轉(zhuǎn)換為 JSON格式的字符串 
def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
        allow_nan=True, cls=None, indent=None, separators=None,
        default=None, sort_keys=False, **kw):
    """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a ``.write()``-supporting file-like object). 我理解為兩個(gè)動(dòng)作,一個(gè)動(dòng)作是將”obj“轉(zhuǎn)換為JSON格式的字符串,還有一個(gè)動(dòng)作是將字符串寫(xiě)入到文件中,也就是說(shuō)文件描述符fp是必須要的參數(shù) """

 

示例代碼:

復(fù)制代碼
復(fù)制代碼
>>> import json
>>> json.dumps([])    # dumps可以格式化所有的基本數(shù)據(jù)類型為字符串
'[]' >>> json.dumps(1) # 數(shù)字 '1' >>> json.dumps('1') # 字符串 '"1"' >>> dict = {"name":"Tom", "age":23} >>> json.dumps(dict) # 字典 '{"name": "Tom", "age": 23}'
復(fù)制代碼
復(fù)制代碼
a = {"name":"Tom", "age":23} with open("test.json", "w", encoding='utf-8') as f: # indent 超級(jí)好用,格式化保存字典,默認(rèn)為None,小于0為零個(gè)空格 f.write(json.dumps(a, indent=4)) # json.dump(a,f,indent=4) # 和上面的效果一樣

保存的文件效果:

 

二. loads 和 load 

loads和load  反序列化方法

       loads 只完成了反序列化,
       load 只接收文件描述符,完成了讀取文件和反序列化

 

 查看源碼:

def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
    """Deserialize ``s`` (a ``str`` instance containing a JSON document) to a Python object.
       將包含str類型的JSON文檔反序列化為一個(gè)python對(duì)象"""
def load(fp, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
    """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing a JSON document) to a Python object.
        將一個(gè)包含JSON格式數(shù)據(jù)的可讀文件飯序列化為一個(gè)python對(duì)象"""

 

實(shí)例:

>>> json.loads('{"name":"Tom", "age":23}')
{'age': 23, 'name': 'Tom'}
復(fù)制代碼
復(fù)制代碼
import json
with open("test.json", "r", encoding='utf-8') as f: aa = json.loads(f.read()) f.seek(0) bb = json.load(f) # 與 json.loads(f.read()) print(aa) print(bb) 

# 輸出: {'name': 'Tom', 'age': 23} {'name': 'Tom', 'age': 23}

復(fù)制代碼
復(fù)制代碼

三. json 和 pickle 模塊

 json模塊和pickle模塊都有  dumps、dump、loads、load四種方法,而且用法一樣。

不用的是json模塊序列化出來(lái)的是通用格式,其它編程語(yǔ)言都認(rèn)識(shí),就是普通的字符串,

而picle模塊序列化出來(lái)的只有python可以認(rèn)識(shí),其他編程語(yǔ)言不認(rèn)識(shí)的,表現(xiàn)為亂碼

不過(guò)picle可以序列化函數(shù),但是其他文件想用該函數(shù),在該文件中需要有該文件的定義(定義和參數(shù)必須相同,內(nèi)容可以不同)

四. python對(duì)象(obj) 與json對(duì)象的對(duì)應(yīng)關(guān)系

復(fù)制代碼
復(fù)制代碼
    +-------------------+---------------+
    | Python            | JSON          |
    +===================+===============+
    | dict              | object        |
    +-------------------+---------------+
    | list, tuple       | array         |
    +-------------------+---------------+
    | str               | string        |
    +-------------------+---------------+
    | int, float        | number        |
    +-------------------+---------------+
    | True              | true          |
    +-------------------+---------------+
    | False             | false         |
    +-------------------+---------------+
    | None              | null          |
    +-------------------+---------------+
復(fù)制代碼
復(fù)制代碼

 

 五. 總結(jié)

 1. json序列化方法:

          dumps:無(wú)文件操作            dump:序列化+寫(xiě)入文件

  2. json反序列化方法:

          loads:無(wú)文件操作              load: 讀文件+反序列化

  3. json模塊序列化的數(shù)據(jù) 更通用

      picle模塊序列化的數(shù)據(jù) 僅python可用,但功能強(qiáng)大,可以序列號(hào)函數(shù)

  4. json模塊可以序列化和反序列化的  數(shù)據(jù)類型 見(jiàn)  python對(duì)象(obj) 與json對(duì)象的對(duì)應(yīng)關(guān)系表

  5. 格式化寫(xiě)入文件利用  indent = 4 

 
   

ElementTree是python的XML處理模塊

 
ElementTree是python的XML處理模塊,它提供了一個(gè)輕量級(jí)的對(duì)象模型。它在Python2.5以后成為Python標(biāo)準(zhǔn)庫(kù)的一部分,但是Python2.4之前需要單獨(dú)安裝。在使用ElementTree模塊時(shí),需要import xml.etree.ElementTree的操作。
ElementTree表示整個(gè)XML節(jié)點(diǎn)樹(shù),而Element表示節(jié)點(diǎn)數(shù)中的一個(gè)單獨(dú)的節(jié)點(diǎn)。

構(gòu)建


ElementTree(tag),其中tag表示根節(jié)點(diǎn),初始化一個(gè)ElementTree對(duì)象。
Element(tag, attrib={}, **extra)函數(shù)用來(lái)構(gòu)造XML的一個(gè)根節(jié)點(diǎn),其中tag表示根節(jié)點(diǎn)的名稱,attrib是一個(gè)可選項(xiàng),表示節(jié)點(diǎn)的屬性。
SubElement(parent, tag, attrib={}, **extra)用來(lái)構(gòu)造一個(gè)已經(jīng)存在的節(jié)點(diǎn)的子節(jié)點(diǎn)
Element.text和SubElement.text表示element對(duì)象的額外的內(nèi)容屬性,Element.tag和Element.attrib分別表示element對(duì)象的標(biāo)簽和屬性。
ElementTree.write(file, encoding='us-ascii', xml_declaration=None, default_namespace=None, method='xml'),函數(shù)新建一個(gè)XML文件,并且將節(jié)點(diǎn)數(shù)數(shù)據(jù)寫(xiě)入XML文件中。
  1. #encoding=utf-8
  2. import xml.etree.ElementTree as ET
'
運(yùn)行

#新建xml文件 def buildNewsXmlFile(): #設(shè)置一個(gè)新節(jié)點(diǎn),并設(shè)置其標(biāo)簽為root root = ET.Element("root")

  1. #在root下新建兩個(gè)子節(jié)點(diǎn),設(shè)置其名稱分別為sina和chinabyte
  2. sina = ET.SubElement(root, "sina")
  3. chinabyte = ET.SubElement(root, "chinabyte")
  4. #在sina下新建兩個(gè)子節(jié)點(diǎn),設(shè)置其節(jié)點(diǎn)名稱分別為number和first
  5. sina_number = ET.SubElement(sina, "number")
  6. sina_number.text = "1"
  7. sina_first = ET.SubElement(sina, "first")
  8. sina_first.text = "http://roll.tech.sina.com.cn/internet_all/index_1.shtml"
  9. #在chinabyte下新建兩個(gè)子節(jié)點(diǎn),設(shè)置其節(jié)點(diǎn)名稱為number和first
  10. chinabyte_number = ET.SubElement(chinabyte, "number")
  11. chinabyte_number.text = "1"
  12. chinabyte_first = ET.SubElement(chinabyte, "first")
  13. chinabyte_first.text = "http://www./more/124566.shtml"
  14. #將節(jié)點(diǎn)數(shù)信息保存在ElementTree中,并且保存為XML格式文件
  15. tree = ET.ElementTree(root)
  16. tree.write("urlfile.xml")</pre>



解析和修改XML文件


ElementTree.parse(source, parser=None),將xml文件加載并返回ElementTree對(duì)象。parser是一個(gè)可選的參數(shù),如果為空,則默認(rèn)使用標(biāo)準(zhǔn)的XMLParser解析器。
ElementTree.getroot(),得到根節(jié)點(diǎn)。返回根節(jié)點(diǎn)的element對(duì)象。

Element.remove(tag),刪除root下名稱為tag的子節(jié)點(diǎn)

以下函數(shù),ElementTree和Element的對(duì)象都包含。
find(match),得到第一個(gè)匹配match的子節(jié)點(diǎn),match可以是一個(gè)標(biāo)簽名稱或者是路徑。返回個(gè)element
findtext(match,default=None),得到第一個(gè)配置的match的element的內(nèi)容
findall(match),得到匹配match下的所有的子節(jié)點(diǎn),match可以是一個(gè)標(biāo)簽或者是路徑,它會(huì)返回一個(gè)list,包含匹配的elements的信息
iter(tag),創(chuàng)建一個(gè)以當(dāng)前節(jié)點(diǎn)為根節(jié)點(diǎn)的iterator。

這里有一個(gè)xml文件
  1. <?xml version="1.0"?>
  2. <data>
  3. <country name="Liechtenstein">
  4. <rank>1</rank>
  5. <year>2008</year>
  6. <gdppc>141100</gdppc>
  7. <neighbor name="Austria" direction="E"/>
  8. <neighbor name="Switzerland" direction="W"/>
  9. </country>
  10. <country name="Singapore">
  11. <rank>4</rank>
  12. <year>2011</year>
  13. <gdppc>59900</gdppc>
  14. <neighbor name="Malaysia" direction="N"/>
  15. </country>
  16. <country name="Panama">
  17. <rank>68</rank>
  18. <year>2011</year>
  19. <gdppc>13600</gdppc>
  20. <neighbor name="Costa Rica" direction="W"/>
  21. <neighbor name="Colombia" direction="E"/>
  22. </country>
  23. </data>

現(xiàn)在是解析xml文件的代碼

  1. #解析Xml文件
  2. def parseXmlFile(xml_name):
  3. #將XMl文件加載并返回一個(gè)ELementTree對(duì)象
  4. tree = ET.parse(xml_name)
'
運(yùn)行
  1. #得到第一個(gè)匹配sina標(biāo)簽的Element對(duì)象
  2. sina = tree.find("contry")
  3. #得到sina的SubElement
  4. for sub_tag in sina:
  5. print sub_tag.text
  6. #得到所有匹配sina標(biāo)簽的Element對(duì)象的list集合
  7. list_contry = tree.findall("contry")
  8. for contry in list_contry:
  9. for sub_tag in contry:
  10. print sub_tag.text
  11. #修改xml文件
  12. for rank in tree.iter('rank')
  13. new_rank = int(rank.text)+1
  14. rank.text = str(new_rank)
  15. rank.set('updated', 'yes')
  16. tree.write(xml_name)
第一次的輸出是:1,2008,14100
第二次的輸出是:1,2008,14100,4,2011,59900,68,2011,13600
修改后的xml文件為
  1. <?xml version="1.0"?>
  2. <data>
  3. <country name="Liechtenstein">
  4. <rank updated="yes">2</rank>
  5. <year>2008</year>
  6. <gdppc>141100</gdppc>
  7. <neighbor name="Austria" direction="E"/>
  8. <neighbor name="Switzerland" direction="W"/>
  9. </country>
  10. <country name="Singapore">
  11. <rank updated="yes">5</rank>
  12. <year>2011</year>
  13. <gdppc>59900</gdppc>
  14. <neighbor name="Malaysia" direction="N"/>
  15. </country>
  16. <country name="Panama">
  17. <rank updated="yes">69</rank>
  18. <year>2011</year>
  19. <gdppc>13600</gdppc>
  20. <neighbor name="Costa Rica" direction="W"/>
  21. <neighbor name="Colombia" direction="E"/>
  22. </country>
  23. </data>
 

configparser 簡(jiǎn)介

 
   

configparser 是 Pyhton 標(biāo)準(zhǔn)庫(kù)中用來(lái)解析配置文件的模塊,并且內(nèi)置方法和字典非常接近。Python2.x 中名為 ConfigParser,3.x 已更名小寫(xiě),并加入了一些新功能。
配置文件的格式如下:

 
   
  1. [DEFAULT]
  2. ServerAliveInterval = 45
  3. Compression = yes
  4. CompressionLevel = 9
  5. ForwardX11 = yes

[bitbucket.org] User = Tom

[topsecret.com] Port: 50022 ForwardX11: no

 
   

“[ ]”包含的為 section,section 下面為類似于 key - value 的配置內(nèi)容;
configparser 默認(rèn)支持 '=’ ':’ 兩種分隔。

 
   
 
   

configparser 常用方法

 
   
初始化實(shí)例
 
   

使用 configparser 首先需要初始化實(shí)例,并讀取配置文件:

 
   
  1. >>> import configparser
  2. >>> config = configparser.ConfigParser() # 注意大小寫(xiě)
  3. >>> config.read("config.ini") # 配置文件的路徑 ["config.ini"]
 
   

或者可以直接讀字典

 
   
  1. >>> parser = configparser.ConfigParser()
  2. >>> parser.read_dict({'section1': {'key1': 'value1',
  3. ... 'key2': 'value2', ... 'key3': 'value3'}, ... 'section2': {'keyA': 'valueA', ... 'keyB': 'valueB', ... 'keyC': 'valueC'}, ... 'section3': {'foo': 'x', ... 'bar': 'y', ... 'baz': 'z'} ... })
 
 
   
獲取所有 sections
 
   
  1. >>> config.sections()
  2. ['bitbucket.org', 'topsecret.com'] # 注意會(huì)過(guò)濾掉[DEFAULT]
 
 
   
獲取指定 section 的 keys & values
 
   
  1. >>> config.items('topsecret.com')
  2. >>>> [('port', '50022'), ('forwardx11', 'no')] # 注意items()返回的字符串會(huì)全變成小寫(xiě)
'
運(yùn)行
 
 
   
獲取指定 section 的 keys
 
   
  1. >>> config.options('topsecret.com')
  2. ['Port', 'ForwardX11']
'
運(yùn)行
 
   
 
   
  1. >>> for option in config['topsecret.com']:
  2. ... print(option)
  3. Port
  4. ForwardX11
 
   
 
   
獲取指定 key 的 value
 
   
  1. >>> config['bitbucket.org']['User']
  2. 'Tom'
 
   
 
   
  1. >>> config.get('bitbucket.org', 'User')
  2. 'Tom'
  3. >>> config.getint('topsecret.com', 'Port') 50022
'
運(yùn)行
 
   
 
   
檢查
 
   
  1. >>> 'DEFAULT' in config
  2. True
  3. >>> 'test' in config['section_test'] False >>> 'Tom' in config['bitbucket.org']['User'] True
'
運(yùn)行
 
   
 
   
  1. >>> config.has_section('bitbucket.org')
  2. True
  3. >>> config.has_option('section_test', 'test') False
'
運(yùn)行
 
   
添加
 
   
  1. >>> config.add_section('Section_1')
  2. >>> config.set('Section_1', 'key_1', 'value_1') # 注意鍵值是用set()方法 >>> config.write(open('config.ini', 'w')) # 一定要寫(xiě)入才生效
'
運(yùn)行
 
   
刪除
 
   
  1. >>> config.remove_option('Section_1', 'key_1')
  2. True
  3. >>> config.remove_section('Section_1') True >>> config.clear() # 清空除[DEFAULT]之外所有內(nèi)容 >>> config.write(open('config.ini', 'w'))
'
運(yùn)行
 
   

 

 
   
 
   

關(guān)于 [DEFAULT]

 
   

[DEFAULT] 一般包含 ini 格式配置文件的默認(rèn)項(xiàng),所以 configparser 部分方法會(huì)自動(dòng)跳過(guò)這個(gè) section 。
前面已經(jīng)提到 sections() 是獲取不到的,還有刪除方法對(duì) [DEFAULT] 也無(wú)效:

 
   
  1. >>> config.remove_section('DEFAULT')
  2. False
  3. >>> config.clear()
  4. >>> 'DEFAULT' in config True >>> 'ForwardX11' in config['DEFAULT'] True >>> config.sections() []
 
   

但指定刪除和修改 [DEFAULT] 里的 keys & values 是可以的:

 
   
  1. >>> config.remove_option('DEFAULT', 'ForwardX11')
  2. True
  3. >>> config.set('DEFAULT', 'ForwardX11','no') >>> config['DEFAULT']['ForwardX11'] 'no'
'
運(yùn)行
 
   
 
   

還有個(gè)特殊的是,has_section() 也無(wú)效,可以和 in 區(qū)別使用

 
   
  1. >>> config.has_section('DEFAULT')
  2. False
  3. >>> 'DEFAULT' in config True
'
運(yùn)行
 
 
   

更多用法請(qǐng)看官方文檔:https://docs./3.6/library/configparser.html

 

randmon(獲取隨機(jī)數(shù))

random.random
random.random()用于生成一個(gè)0到1的隨機(jī)符點(diǎn)數(shù): 0 <= n < 1.0

 
   

random.uniform
random.uniform(a, b),用于生成一個(gè)指定范圍內(nèi)的隨機(jī)符點(diǎn)數(shù),兩個(gè)參數(shù)其中一個(gè)是上限,一個(gè)是下限。如果a > b,則生成的隨機(jī)數(shù)n: a <= n <= b。如果 a <b, 則 b <= n <= a

 
   
復(fù)制代碼 代碼如下:
 
   

print random.uniform(10, 20)
print random.uniform(20, 10)
# 18.7356606526
# 12.5798298022 
 
   

random.randint
random.randint(a, b),用于生成一個(gè)指定范圍內(nèi)的整數(shù)。其中參數(shù)a是下限,參數(shù)b是上限,生成的隨機(jī)數(shù)n: a <= n <= b

 
   
復(fù)制代碼 代碼如下:
 
   

print random.randint(12, 20)  # 生成的隨機(jī)數(shù) n: 12 <= n <= 20
print random.randint(20, 20)  # 結(jié)果永遠(yuǎn)是20    
# print random.randint(20, 10)  # 該語(yǔ)句是錯(cuò)誤的。下限必須小于上限
 
   

random.randrange
random.randrange([start], stop[, step]),從指定范圍內(nèi),按指定基數(shù)遞增的集合中 獲取一個(gè)隨機(jī)數(shù)。如:random.randrange(10, 100, 2),結(jié)果相當(dāng)于從[10, 12, 14, 16, ... 96, 98]序列中獲取一個(gè)隨機(jī)數(shù)。random.randrange(10, 100, 2)在結(jié)果上與 random.choice(range(10, 100, 2) 等效

 
   

random.choice
random.choice從序列中獲取一個(gè)隨機(jī)元素。其函數(shù)原型為:random.choice(sequence)。參數(shù)sequence表示一個(gè)有序類型。這里要說(shuō)明 一下:sequence在python不是一種特定的類型,而是泛指一系列的類型。list, tuple, 字符串都屬于sequence。有關(guān)sequence可以查看python手冊(cè)數(shù)據(jù)模型這一章。下面是使用choice的一些例子:

 
   
復(fù)制代碼 代碼如下:
 
   

print random.choice("學(xué)習(xí)Python")
print random.choice(["JGood", "is", "a", "handsome", "boy"])
print random.choice(("Tuple", "List", "Dict")) 
 
   

random.shuffle
random.shuffle(x[, random]),用于將一個(gè)列表中的元素打亂。如:

 
   
復(fù)制代碼 代碼如下:
 
   

p = ["Python", "is", "powerful", "simple", "and so on..."]
random.shuffle(p)
print p
# ['powerful', 'simple', 'is', 'Python', 'and so on...'] 
 
   

random.sample
random.sample(sequence, k),從指定序列中隨機(jī)獲取指定長(zhǎng)度的片斷。sample函數(shù)不會(huì)修改原有序列

 
   
復(fù)制代碼 代碼如下:
 
   

list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
slice = random.sample(list, 5)  # 從list中隨機(jī)獲取5個(gè)元素,作為一個(gè)片斷返回
print slice
print list  # 原有序列并沒(méi)有改變
 
   


隨機(jī)整數(shù):

 
   
復(fù)制代碼 代碼如下:
 
   
>>> import random
>>> random.randint(0,99)
# 21
 
   

隨機(jī)選取0到100間的偶數(shù):

 
   
復(fù)制代碼 代碼如下:
 
   
>>> import random
>>> random.randrange(0, 101, 2)
# 42
 
   

隨機(jī)浮點(diǎn)數(shù):

 
   
復(fù)制代碼 代碼如下:
 
   
>>> import random
>>> random.random()
0.85415370477785668
>>> random.uniform(1, 10)
# 5.4221167969800881
 
   

隨機(jī)字符:

 
   
復(fù)制代碼 代碼如下:
 
   
>>> import random
>>> random.choice('abcdefg&#%^*f')
# 'd'
 
   

多個(gè)字符中選取特定數(shù)量的字符:

 
   
復(fù)制代碼 代碼如下:
 
   
>>> import random
random.sample('abcdefghij', 3)
# ['a', 'd', 'b']
 
   

多個(gè)字符中選取特定數(shù)量的字符組成新字符串:

 
   
復(fù)制代碼 代碼如下:
 
   
>>> import random
>>> import string
>>> string.join( random.sample(['a','b','c','d','e','f','g','h','i','j'], 3) ).replace(" ","")
# 'fih'
 
   

隨機(jī)選取字符串:

 
   
復(fù)制代碼 代碼如下:
 
   
>>> import random
>>> random.choice ( ['apple', 'pear', 'peach', 'orange', 'lemon'] )
# 'lemon'
 
   

洗牌:

 
   
復(fù)制代碼 代碼如下:
 
   
>>> import random
>>> items = [1, 2, 3, 4, 5, 6]
>>> random.shuffle(items)
>>> items
# [3, 2, 5, 6, 4, 1]
 
   

 

shutil模塊


引入: import shutil

copy()
  1. 功能:復(fù)制文件
  2. 格式:shutil.copy('來(lái)源文件','目標(biāo)地址')
  3. 返回值:復(fù)制之后的路徑
copy2()
  1. 功能:復(fù)制文件,保留元數(shù)據(jù)
  2. 格式:shutil.copy2('來(lái)源文件','目標(biāo)地址')
  3. 返回值:復(fù)制之后的路徑
copyfileobj()
  1. 將一個(gè)文件的內(nèi)容拷貝的另外一個(gè)文件當(dāng)中
  2. 格式:shutil.copyfileobj(open(來(lái)源文件,'r'),open('目標(biāo)文件','w'))
  3. 返回值:無(wú)
copyfile()
  1. 功能:將一個(gè)文件的內(nèi)容拷貝的另外一個(gè)文件當(dāng)中
  2. 格式:shutil.copyfile(來(lái)源文件,目標(biāo)文件)
  3. 返回值:目標(biāo)文件的路徑
copytree()
  1. 功能:復(fù)制整個(gè)文件目錄
  2. 格式:shutil.copytree(來(lái)源目錄,目標(biāo)目錄)
  3. 返回值:目標(biāo)目錄的路徑
  4. 注意:無(wú)論文件夾是否為空,均可以復(fù)制,而且會(huì)復(fù)制文件夾中的所有內(nèi)容
copymode()
功能:拷貝權(quán)限
copystat()
功能:拷貝元數(shù)據(jù)(狀態(tài))
rmtree()
  1. 功能:移除整個(gè)目錄,無(wú)論是否空
  2. 格式:shutil.rmtree(目錄路徑)
  3. 返回值:無(wú)
move()
  1. 功能:移動(dòng)文件或者文件夾
  2. 格式:shutil.move(來(lái)源地址,目標(biāo)地址)
  3. 返回值:目標(biāo)地址
which()
  1. 功能:檢測(cè)命令對(duì)應(yīng)的文件路徑
  2. 格式:shutil.which('命令字符串’)
  3. 返回值:命令文件所在位置
  4. 注意:window和linux不太一樣。 window的命令都是.exe結(jié)尾,linux則不是
disk_usage()
  1. 功能:檢測(cè)磁盤(pán)使用信息
  2. 格式:disk_usage('盤(pán)符’)
  3. 返回值:元組

歸檔和解包操作


歸檔:將多個(gè)文件合并到一個(gè)文件當(dāng)中,這種操作方式就是歸檔。

解包:將歸檔的文件進(jìn)行釋放。

壓縮:壓縮時(shí)將多個(gè)文件進(jìn)行有損或者無(wú)損的合并到一個(gè)文件當(dāng)中。

解壓縮:就是壓縮的反向操作,將壓縮文件中的多個(gè)文件,釋放出來(lái)。

注意:壓縮屬于歸檔!
make_archive()
  1. 功能:歸檔函數(shù),歸檔操作
  2. 格式:shutil.make_archive('目標(biāo)文件路徑','歸檔文件后綴','需要?dú)w檔的目錄')
  3. 返回值:歸檔文件的最終路徑
unpack_archive()
  1. 功能:解包操作
  2. 格式:shutil.unpack_archive('歸檔文件路徑','解包目標(biāo)文件夾')
  3. 返回值:None
  4. 注意:文件夾不存在會(huì)新建文件夾
get_archive_formats()
  1. 功能:獲取當(dāng)前系統(tǒng)已注冊(cè)的歸檔文件格式(后綴)
  2. 格式:shutil.get_archive_formats()
  3. 返回值:列表 [(后綴,解釋),(后綴,解釋),(后綴,解釋)...]
get_unpack_formats()
  1. 功能:獲取當(dāng)前系統(tǒng)已經(jīng)注冊(cè)的解包文件格式(后綴)
  2. 格式:shutil.get_unpack_formats()
  3. 返回值:列表 [(后綴,解釋),(后綴,解釋),(后綴,解釋)...]
 

paramiko

 
   

paramiko是一個(gè)用于做遠(yuǎn)程控制的模塊,使用該模塊可以對(duì)遠(yuǎn)程服務(wù)器進(jìn)行命令或文件操作,值得一說(shuō)的是,fabric和ansible內(nèi)部的遠(yuǎn)程管理就是使用的paramiko來(lái)現(xiàn)實(shí)。

 
   

1、下載安裝

 
   
1
2
3
pycrypto,由于 paramiko 模塊內(nèi)部依賴pycrypto,所以先下載安裝pycrypto
pip3 install pycrypto
pip3 install paramiko
 
   

2、模塊使用

 
   
復(fù)制代碼
復(fù)制代碼
#!/usr/bin/env python
#coding:utf-8

import paramiko

ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('192.168.1.108', 22, 'alex', '123') stdin, stdout, stderr = ssh.exec_command('df') print stdout.read() ssh.close();

復(fù)制代碼
復(fù)制代碼
 
   
復(fù)制代碼
復(fù)制代碼
import paramiko

private_key_path = '/home/auto/.ssh/id_rsa' key = paramiko.RSAKey.from_private_key_file(private_key_path)

ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('主機(jī)名 ', 端口, '用戶名', key)

stdin, stdout, stderr = ssh.exec_command('df') print stdout.read() ssh.close()

復(fù)制代碼
復(fù)制代碼
 
   
復(fù)制代碼
復(fù)制代碼
import os,sys
import paramiko

t = paramiko.Transport(('182.92.219.86',22)) t.connect(username='wupeiqi',password='123') sftp = paramiko.SFTPClient.from_transport(t) sftp.put('/tmp/test.py','/tmp/test.py') t.close()

import os,sys import paramiko

t = paramiko.Transport(('182.92.219.86',22)) t.connect(username='wupeiqi',password='123') sftp = paramiko.SFTPClient.from_transport(t) sftp.get('/tmp/test.py','/tmp/test2.py') t.close()

復(fù)制代碼
復(fù)制代碼
 
   
復(fù)制代碼
復(fù)制代碼
import paramiko

pravie_key_path = '/home/auto/.ssh/id_rsa' key = paramiko.RSAKey.from_private_key_file(pravie_key_path)

t = paramiko.Transport(('182.92.219.86',22)) t.connect(username='wupeiqi',pkey=key)

sftp = paramiko.SFTPClient.from_transport(t) sftp.put('/tmp/test3.py','/tmp/test3.py')

t.close()

import paramiko

pravie_key_path = '/home/auto/.ssh/id_rsa' key = paramiko.RSAKey.from_private_key_file(pravie_key_path)

t = paramiko.Transport(('182.92.219.86',22)) t.connect(username='wupeiqi',pkey=key)

sftp = paramiko.SFTPClient.from_transport(t) sftp.get('/tmp/test3.py','/tmp/test4.py')

t.close()

復(fù)制代碼
復(fù)制代碼
 
   

requests

 
   

Python標(biāo)準(zhǔn)庫(kù)中提供了:urllib等模塊以供Http請(qǐng)求,但是,它的 API 太渣了。它是為另一個(gè)時(shí)代、另一個(gè)互聯(lián)網(wǎng)所創(chuàng)建的。它需要巨量的工作,甚至包括各種方法覆蓋,來(lái)完成最簡(jiǎn)單的任務(wù)。

 
   
import urllib.request

f = urllib.request.urlopen('http://www.//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508') result = f.read().decode('utf-8')

 
   
復(fù)制代碼
復(fù)制代碼
import urllib.request

req = urllib.request.Request('http://www./') req.add_header('Referer', 'http://www./') r = urllib.request.urlopen(req)

result = f.read().decode('utf-8')

復(fù)制代碼
復(fù)制代碼
 
   

注:更多見(jiàn)Python官方文檔:https://docs./3.5/library/urllib.request.html#module-urllib.request

 
   

Requests 是使用 Apache2 Licensed 許可證的 基于Python開(kāi)發(fā)的HTTP 庫(kù),其在Python內(nèi)置模塊的基礎(chǔ)上進(jìn)行了高度的封裝,從而使得Pythoner進(jìn)行網(wǎng)絡(luò)請(qǐng)求時(shí),變得美好了許多,使用Requests可以輕而易舉的完成瀏覽器可有的任何操作。

 
   

1、安裝模塊

 
   
1
pip3 install requests
 
   

2、使用模塊

 
   
復(fù)制代碼
復(fù)制代碼
# 1、無(wú)參數(shù)實(shí)例
 
import requests
 
ret = requests.get('https://github.com/timeline.json') print(ret.url) print(ret.text) # 2、有參數(shù)實(shí)例 import requests payload = {'key1': 'value1', 'key2': 'value2'} ret = requests.get("http:///get", params=payload) print(ret.url) print(ret.text)
復(fù)制代碼
復(fù)制代碼
 
   
復(fù)制代碼
復(fù)制代碼
# 1、基本POST實(shí)例
 
import requests
 
payload = {'key1': 'value1', 'key2': 'value2'} ret = requests.post("http:///post", data=payload) print(ret.text) # 2、發(fā)送請(qǐng)求頭和數(shù)據(jù)實(shí)例 import requests import json url = 'https://api.github.com/some/endpoint' payload = {'some': 'data'} headers = {'content-type': 'application/json'} ret = requests.post(url, data=json.dumps(payload), headers=headers) print(ret.text) print(ret.cookies)
復(fù)制代碼
復(fù)制代碼
 
   
復(fù)制代碼
復(fù)制代碼
requests.get(url, params=None, **kwargs)
requests.post(url, data=None, json=None, **kwargs)
requests.put(url, data=None, **kwargs)
requests.head(url, **kwargs)
requests.delete(url, **kwargs)
requests.patch(url, data=None, **kwargs) requests.options(url, **kwargs) # 以上方法均是在此方法的基礎(chǔ)上構(gòu)建 requests.request(method, url, **kwargs)
復(fù)制代碼
復(fù)制代碼
 
   

更多requests模塊相關(guān)的文檔見(jiàn):http://cn./zh_CN/latest/

 
   

3、Http請(qǐng)求和XML實(shí)例

 
   

實(shí)例:檢測(cè)QQ賬號(hào)是否在線

 
   
復(fù)制代碼
復(fù)制代碼
import urllib
import requests
from xml.etree import ElementTree as ET 

# 使用內(nèi)置模塊urllib發(fā)送HTTP請(qǐng)求,或者XML格式內(nèi)容 <> f = urllib.request.urlopen('http://www.//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508') result = f.read().decode('utf-8') >

# 使用第三方模塊requests發(fā)送HTTP請(qǐng)求,或者XML格式內(nèi)容 r = requests.get('http://www.//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508') result = r.text

# 解析XML格式內(nèi)容 node = ET.XML(result)

# 獲取內(nèi)容 if node.text == "Y": print("在線") else: print("離線")

復(fù)制代碼
復(fù)制代碼
 
   

實(shí)例:查看火車停靠信息

 
   
復(fù)制代碼
復(fù)制代碼
import urllib
import requests
from xml.etree import ElementTree as ET 

# 使用內(nèi)置模塊urllib發(fā)送HTTP請(qǐng)求,或者XML格式內(nèi)容 <> f = urllib.request.urlopen('http://www./WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G666&UserID=') result = f.read().decode('utf-8') >

# 使用第三方模塊requests發(fā)送HTTP請(qǐng)求,或者XML格式內(nèi)容 r = requests.get('http://www./WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G666&UserID=') result = r.text

# 解析XML格式內(nèi)容 root = ET.XML(result) for node in root.iter('TrainDetailInfo'): print(node.find('TrainStation').text,node.find('StartTime').text,node.tag,node.attrib)

復(fù)制代碼
復(fù)制代碼
 
   

注:更多接口猛擊這里

 
   

paramiko模塊

 
   

 

 
   
復(fù)制代碼
復(fù)制代碼
import paramiko

# 創(chuàng)建SSH對(duì)象 ssh = paramiko.SSHClient() # 允許連接不在known_hosts文件上的主機(jī) ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 連接服務(wù)器 ssh.connect(hostname="192.168.0.99", port=22, username="root", password="rootroot") # 執(zhí)行命令 stdin, stdout, stderr = ssh.exec_command('df') # 獲取結(jié)果 result = stdout.read().decode() # 獲取錯(cuò)誤提示(stdout、stderr只會(huì)輸出其中一個(gè)) err = stderr.read() # 關(guān)閉連接 ssh.close() print(stdin, result, err)

復(fù)制代碼
復(fù)制代碼
 
   

注:如果注釋“ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())”這句,會(huì)報(bào)錯(cuò)。

 
   

 
   

類似問(wèn)題可以為linux系統(tǒng)中~/.ssh/known_hosts文件中的內(nèi)容。

 
   

 二、實(shí)現(xiàn)SFTP功能

 
   
復(fù)制代碼
復(fù)制代碼
import paramiko
# 連接虛擬機(jī)centos上的ip及端口
transport = paramiko.Transport(("192.168.0.99", 22)) transport.connect(username="root", password="rootroot") # 將實(shí)例化的Transport作為參數(shù)傳入SFTPClient中 sftp = paramiko.SFTPClient.from_transport(transport) # 將“calculator.py”上傳到filelist文件夾中 sftp.put('D:\python庫(kù)\Python_shell\day05\calculator.py', '/filelist/calculator.py') # 將centos中的aaa.txt文件下載到桌面 sftp.get('/filedir/aaa.txt', r'C:\Users\duany_000\Desktop\test_aaa.txt') transport.close()
復(fù)制代碼
復(fù)制代碼
 
   

注:如果遇到Windows中路徑問(wèn)題,鏈接如下網(wǎng)址http://blog.csdn.net/elang6962/article/details/68068126

 
   

三、使用秘鑰實(shí)現(xiàn)SSH功能

 
   
復(fù)制代碼
復(fù)制代碼
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('id_rsa31') # 創(chuàng)建SSH對(duì)象 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 連接服務(wù)器 ssh.connect(hostname='192.168.79.9', port=22, username='root', pkey=private_key) stdin, stdout, stderr = ssh.exec_command('ifconfig') res_out = stdout.read() print(res_out.decode()) ssh.close()
復(fù)制代碼
復(fù)制代碼
 
   

四、使用秘鑰實(shí)現(xiàn)SFTP功能

 
   
復(fù)制代碼
 
   
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('id_rsa31') # 連接虛擬機(jī)centos上的ip及端口 transport = paramiko.Transport(("192.168.79.9", 22)) transport.connect(username="root", pkey=private_key) # 將實(shí)例化的Transport作為參數(shù)傳入SFTPClient中 sftp = paramiko.SFTPClient.from_transport(transport) # 將“calculator.py”上傳到filelist文件夾中 sftp.put('D:\python庫(kù)\Python_shell\day05\calculator.py', '/filedir/calculator.py') # 將centos中的aaa.txt文件下載到桌面 sftp.get('/filedir/oldtext.txt', r'C:\Users\duany_000\Desktop\oldtext.txt') transport.close()








    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多