time、random以及序列化模块
一、 time模塊
在Python中,通常有這幾種方式來表示時(shí)間:
- 時(shí)間戳(timestamp):通常來說,時(shí)間戳表示的是從1970年1月1日00:00:00開始按秒計(jì)算的偏移量。我們運(yùn)行“type(time.time())”,返回的是float類型。
- 格式化的時(shí)間字符串(Format String)
- 結(jié)構(gòu)化的時(shí)間(struct_time):struct_time元組共有9個(gè)元素共九個(gè)元素:(年,月,日,時(shí),分,秒,一年中第幾周,一年中第幾天,夏令時(shí)),可以通過點(diǎn)來調(diào)用具體里面的值。 import time
#--------------------------我們先以當(dāng)前時(shí)間為準(zhǔn),讓大家快速認(rèn)識(shí)三種形式的時(shí)間
print(time.time()) # 時(shí)間戳:1487130156.419527
f = time.localtime(time.time() - 86000 * 3)? # 150000000 秒? 86000,三天前的結(jié)構(gòu)化時(shí)間 print(time.strftime("%Y-%m-%d %X")) #格式化的時(shí)間字符串:'2017-02-15 11:40:53',當(dāng)前字符串時(shí)間,
print(time.strftime('%Y-%m-%d %H:%M:%S',f)) # f是結(jié)構(gòu)化時(shí)間 將結(jié)構(gòu)化時(shí)間轉(zhuǎn)化為字符串時(shí)間print(time.localtime()) #本地時(shí)區(qū)的struct_time print(time.gmtime()) #UTC時(shí)區(qū)的struct_time %y 兩位數(shù)的年份表示(00-99) %Y 四位數(shù)的年份表示(000-9999) %m 月份(01-12) %d 月內(nèi)中的一天(0-31) %H 24小時(shí)制小時(shí)數(shù)(0-23) %I 12小時(shí)制小時(shí)數(shù)(01-12) %M 分鐘數(shù)(00=59) %S 秒(00-59) %a 本地簡化星期名稱 %A 本地完整星期名稱 %b 本地簡化的月份名稱 %B 本地完整的月份名稱 %c 本地相應(yīng)的日期表示和時(shí)間表示 %j 年內(nèi)的一天(001-366) %p 本地A.M.或P.M.的等價(jià)符 %U 一年中的星期數(shù)(00-53)星期天為星期的開始 %w 星期(0-6),星期天為星期的開始 %W 一年中的星期數(shù)(00-53)星期一為星期的開始 %x 本地相應(yīng)的日期表示 %X 本地相應(yīng)的時(shí)間表示 %Z 當(dāng)前時(shí)區(qū)的名稱 相應(yīng)參數(shù)?
-
? ? 其中計(jì)算機(jī)認(rèn)識(shí)的時(shí)間只能是'時(shí)間戳'格式,而程序員可處理的或者說人類能看懂的時(shí)間有: '格式化的時(shí)間字符串','結(jié)構(gòu)化的時(shí)間'?,于是有了下圖的轉(zhuǎn)換關(guān)系
- 結(jié)構(gòu)化的時(shí)間(struct_time):struct_time元組共有9個(gè)元素共九個(gè)元素:(年,月,日,時(shí),分,秒,一年中第幾周,一年中第幾天,夏令時(shí)),可以通過點(diǎn)來調(diào)用具體里面的值。 import time
#--------------------------我們先以當(dāng)前時(shí)間為準(zhǔn),讓大家快速認(rèn)識(shí)三種形式的時(shí)間
print(time.time()) # 時(shí)間戳:1487130156.419527
?結(jié)合上圖可得:
#--------------------------按圖1轉(zhuǎn)換時(shí)間 1、localtime([secs])將一個(gè)時(shí)間戳轉(zhuǎn)換為當(dāng)前時(shí)區(qū)的struct_time。secs參數(shù)未提供,則以當(dāng)前時(shí)間為準(zhǔn)。 time.localtime() # time.struct_time(tm_year=2018, tm_mon=9, tm_mday=6, tm_hour=20, tm_min=56, tm_sec=16, tm_wday=3, tm_yday=249, tm_isdst=0) 當(dāng)前時(shí)間 time.localtime(1473525444.037215) # time.struct_time(tm_year=2016, tm_mon=9, tm_mday=11, tm_hour=0, tm_min=37, tm_sec=24, tm_wday=6, tm_yday=255, tm_isdst=0) 給定時(shí)間的格式化時(shí)間2、gmtime([secs]) 和localtime()方法類似,gmtime()方法是將一個(gè)時(shí)間戳轉(zhuǎn)換為UTC時(shí)區(qū)(0時(shí)區(qū))的struct_time。 time.gmtime() # 結(jié)果 time.struct_time(tm_year=2011, tm_mon=5, tm_mday=5, tm_hour=6, tm_min=19,tm_sec=48, tm_wday=3, tm_yday=125, tm_isdst=0) 3、mktime(t) : 將一個(gè)struct_time轉(zhuǎn)化為時(shí)間戳。
print(time.mktime(time.localtime())) #1473525749.0 4、strftime(format[, t]) : 把一個(gè)代表時(shí)間的元組或者struct_time(如由time.localtime()和time.gmtime()返回)轉(zhuǎn)化為格式化的時(shí)間字符串。如果t未指定,將傳入time.localtime()。
#如果元組中任何一個(gè)元素越界,ValueError的錯(cuò)誤將會(huì)被拋出。 print(time.strftime("%Y-%m-%d %X", time.localtime())) #2016-09-11 00:49:56
print(time.strftime('%Y--%m--%d %X',)) #2018--09--06 21:04:16 # 5、time.strptime(string[, format]) # 把一個(gè)格式化時(shí)間字符串轉(zhuǎn)化為struct_time。實(shí)際上它和strftime()是逆操作。
print(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)
#在這個(gè)函數(shù)中,format默認(rèn)為:"%a %b %d %H:%M:%S %Y"。
總結(jié):
? ? time是datetime的底層模塊
? ? 時(shí)間戳?xí)r間-localtime/gmtime-> 結(jié)構(gòu)化時(shí)間 -strftime-> 格式化時(shí)間
? ? 時(shí)間戳?xí)r間<-mktime- 結(jié)構(gòu)化時(shí)間 <-strptime- 格式化時(shí)間
?
?
1、當(dāng)前年月日的凌晨12點(diǎn)對應(yīng)的時(shí)間戳?xí)r間是多少 today =time.strftime('%Y-%m-%d') # 格式化時(shí)間 locals_time=time.strptime(today,'%Y-%m-%d') # 獲取到結(jié)構(gòu)化時(shí)間,默認(rèn)返回凌晨時(shí)間 print(time.mktime(locals_time)) # 獲取時(shí)間戳 today =time.strftime('%Y-%m-%d %X') # 格式化時(shí)間 locals_time=time.strptime(today,'%Y-%m-%d %X') # 獲取到結(jié)構(gòu)化時(shí)間,默認(rèn)返回當(dāng)前時(shí)間 print(time.mktime(locals_time)) # 獲取時(shí)間戳 print(time.time()) 公司內(nèi)的時(shí)間操作? 例題: 1、將s時(shí)間往前推30天 import time s = '2019-03-20 10:40:00' local_time = time.strptime(s,'%Y-%m-%d %X') # 轉(zhuǎn)化成結(jié)構(gòu)化時(shí)間 print(local_time) #time.struct_time(tm_year=2019, tm_mon=3, tm_mday=20, tm_hour=10, tm_min=40, tm_sec=0, tm_wday =2, tm_yday=79, tm_isdst=-1) x=time.mktime(local_time)+30 * 86000 # 轉(zhuǎn)化成時(shí)間戳 new_time = time.localtime(x) #將時(shí)間戳轉(zhuǎn)化為結(jié)構(gòu)化時(shí)間 print(new_time) new_time_local =time.strftime('%Y-%m-%d %X',new_time) # 將結(jié)構(gòu)化時(shí)間轉(zhuǎn)化為字符串格式 print(new_time_local)#準(zhǔn)確答案 import datetime #將當(dāng)前時(shí)間推前30天 print(datetime.datetime.now()-datetime.timedelta(30)) 當(dāng)前推后30天?
?
?
含有月份周期的時(shí)間表示:
?
?結(jié)合上圖可得:
#--------------------------按圖2轉(zhuǎn)換時(shí)間 # asctime([t]) : 把一個(gè)表示時(shí)間的元組或者struct_time表示為這種形式:'Sun Jun 20 23:21:05 1993'。 # 如果沒有參數(shù),將會(huì)將time.localtime()作為參數(shù)傳入。 print(time.asctime())#Sun Sep 11 00:43:43 2016# ctime([secs]) : 把一個(gè)時(shí)間戳(按秒計(jì)算的浮點(diǎn)數(shù))轉(zhuǎn)化為time.asctime()的形式。如果參數(shù)未給或者為 # None的時(shí)候,將會(huì)默認(rèn)time.time()為參數(shù)。它的作用相當(dāng)于time.asctime(time.localtime(secs))。 print(time.ctime()) # Sun Sep 11 00:46:38 2016 print(time.ctime(time.time())) # Sun Sep 11 00:46:38 2016 輸入某年某月某日,判斷是這一年中的第幾天?(用內(nèi)置模塊實(shí)現(xiàn))import time input_ = input('請輸入年月日:') time_local = time.strptime(input_,'%Y-%m-%d %X') print(time_local.tm_yday) # 結(jié)構(gòu)化時(shí)間調(diào)用里面的參數(shù) 結(jié)構(gòu)化時(shí)間點(diǎn)功能?補(bǔ)充:
1、time.clock():這個(gè)需要注意,在不同的系統(tǒng)上含義不同。在UNIX系統(tǒng)上,它返回的是“進(jìn)程時(shí)間”,它是用秒表示的浮點(diǎn)數(shù)(時(shí)間戳)。而在WINDOWS中,第一次調(diào)用,返回的是進(jìn)程運(yùn)行的實(shí)際時(shí)間。而第二次之后的調(diào)用是自第一次調(diào)用以后到現(xiàn)在的運(yùn)行時(shí)間。(實(shí)際上是以WIN32上QueryPerformanceCounter()為基礎(chǔ),它比毫秒表示更為精確)也就是CPU工作時(shí)間。
2、time.sleep(secs):線程推遲指定的時(shí)間運(yùn)行。單位為秒
?二、datetime模塊
#時(shí)間加減 import datetime# print(datetime.datetime.now()) #返回 2016-08-19 12:47:03.941925,返回當(dāng)前時(shí)間 # print(datetime.date.fromtimestamp(time.time()) ) # 時(shí)間戳直接轉(zhuǎn)成日期格式 2016-08-19 # print(datetime.datetime.now() ) # print(datetime.datetime.now() + datetime.timedelta(3)) #當(dāng)前時(shí)間+3天 # print(datetime.datetime.now() + datetime.timedelta(-3)) #當(dāng)前時(shí)間-3天 # print(datetime.datetime.now() + datetime.timedelta(hours=3)) #當(dāng)前時(shí)間+3小時(shí) # print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #當(dāng)前時(shí)間+30分 # c_time = datetime.datetime.now() # print(c_time.replace(minute=3,hour=2)) #時(shí)間替換 2018-09-07 02:03:37.591115 其實(shí)就是修改時(shí)間import datetime
t = datetime.datetime.now() # 時(shí)間操作符獲取對象
print(t.date())? ?# 就可以訪問具體的天數(shù)
print(t.time())
print(t.timestamp())? #時(shí)間戳
print(t.day)
print(t.month)
?
?三、random模塊?
import random print(random.random()) #(0,1)----float 大于0且小于1之間的小數(shù) print(random.randint(1,3)) #[1,3] 大于等于1且小于等于3之間的整數(shù) print(random.randrange(1,3)) #[1,3) 大于等于1且小于3之間的整數(shù) print(random.choice([1,'23',[4,5]])) #1或者23或者[4,5],這里可以填字符串,在字符串中隨機(jī)一個(gè)字母print(random.choices([1,'23',[4,5],'3','4'],k=3)) #['4', '23', '23'],隨機(jī)3個(gè)
print(random.sample([1,'23',[4,5]],2)) #列表元素任意2個(gè)組合 print(random.uniform(1,3)) #大于1小于3的小數(shù),如1.927109612082716 item=[1,3,5,7,9] random.shuffle(item) #打亂item的順序,相當(dāng)于"洗牌" print(item)
例: 驗(yàn)證碼生成器:
import random
def make_code(n):
res = ''
for i in range(n):
s1 = chr(random.randint(65,90)) # 生成字母chr
s2 = str(random.randint(0,9))
res += random.choice([s1,s2])
return res
print(make_code(9)) # H53FVG8K4 ?
?
?四、os模塊
os模塊是與操作系統(tǒng)交互的一個(gè)接口
import os print(os.getcwd()) # 獲取當(dāng)前工作目錄,即當(dāng)前python腳本工作的目錄路徑 D:\pycharm code\離校\時(shí)間模塊 os.chdir("D:\pycharm code\day2") # 改變當(dāng)前腳本工作目錄;相當(dāng)于shell下cd print(os.getcwd()) # D:\pycharm code\day2 當(dāng)再一次判斷位置時(shí),發(fā)生了變化# print(os.curdir) # . # print(os.pardir) # ..# os.makedirs('abc\\alex') # 在day2(當(dāng)前工作目錄)下生成abc文件,在abc下再生成alex文件 # os.makedirs('dirname1/dirname2') # 可生成多層遞歸目錄 (已存在的文件名不能再一次生成)#os.removedirs('dirname1/dirname2') # 若目錄為空,則刪除,并遞歸到上一級目錄,如若也為空,則刪除,依此類推# os.mkdir('dirname') # 生成單級目錄;相當(dāng)于shell中mkdir dirname # os.rmdir('dirname') # 刪除單級空目錄,若目錄不為空則無法刪除,報(bào)錯(cuò);相當(dāng)于shell中rmdir dirname#print(os.listdir('.')) # 列出指定目錄下的所有文件和子目錄,包括隱藏文件,并以列表方式打印,['abc', '今日大綱', '作業(yè)講解.py']# os.remove('哈哈哈') # 刪除一個(gè)文件 # os.rename("abc","newname") # 重命名文件/目錄 舊名字,新名字print(os.stat('./newname')) # 獲取文件目錄信息('path/filename') os.stat_result(st_mode=16895, st_ino=2533274790436658,# st_dev=2092381065,st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1536304047, st_mtime=1536300456,st_ctime=1536300456) s = os.stat('./newname') print(s.st_size) # 可打印文件大小print(os.sep) # 輸出操作系統(tǒng)特定的路徑分隔符,win下為"\\",Linux下為"/" s=os.linesep # 輸出當(dāng)前平臺(tái)使用的行終止符,win下為"\r\n",Linux下為"\n",Mac下為 '\r' print('c,jjj%s'%s,end=' ') print('哈哈')print(os.pathsep) # 輸出用于分割文件路徑的字符串 win下為;,Linux下為: print(os.name) # 輸出字符串指示當(dāng)前使用平臺(tái)。win->'nt'; Linux->'posix'#os.system("ping www.baidu.com -t") # 運(yùn)行shell命令,直接顯示,cmd窗口 # print(os.environ) # 獲取系統(tǒng)環(huán)境變量 # print(os.path.abspath('D:\BaiduNetdiskDownload')) # 返回path規(guī)范化的絕對路徑print(os.path.split('D:\BaiduNetdiskDownload')) # 將path分割成目錄和文件名二元組返回 ('D:\\', 'BaiduNetdiskDownload') print(os.path.dirname('D:\BaiduNetdiskDownload')) # 返回path的目錄。其實(shí)就是os.path.split(path)的第一個(gè)元素 D:\ print(os.path.basename('D:\BaiduNetdiskDownload')) # 返回path最后的文件名。如何path以/或\結(jié)尾,那么就會(huì)返回空值。 # 即os.path.split(path)的第二個(gè)元素 BaiduNetdiskDownloadprint(os.path.exists('D:\BaiduNetdiskDownload')) # 如果path存在,返回True;如果path不存在,返回False True print(os.path.isabs('D:\BaiduNetdiskDownload')) # 如果path是絕對路徑,返回True True print(os.path.isfile('D:\BaiduNetdiskDownload')) # 如果path是一個(gè)存在的文件,返回True。否則返回False False print(os.path.isdir('D:\BaiduNetdiskDownload')) # 如果path是一個(gè)存在的目錄,則返回True。否則返回False True #os.path.join(path1[, path2[, ...]]) # 將多個(gè)路徑組合后返回,第一個(gè)絕對路徑之前的參數(shù)將被忽略 print(os.path.join('/my/','name/is/','vampire_techking')) # /my/name/is/vampire_techking,注意這里的第二個(gè)參數(shù)不能以/開頭print(os.path.getatime('D:\BaiduNetdiskDownload')) # 返回path所指向的文件或者目錄的最后存取時(shí)間 1536305083.0908828 print(os.path.getmtime('D:\BaiduNetdiskDownload')) # 返回path所指向的文件或者目錄的最后修改時(shí)間 print(os.path.getsize('D:\BaiduNetdiskDownload')) # 返回path的大小?簡要總結(jié):
os.path.abspath(path) #返回絕對路徑 os.path.basename(path) #返回文件名 os.path.commonprefix(list) #返回list(多個(gè)路徑)中,所有path共有的最長的路徑。 os.path.dirname(path) #返回文件路徑 os.path.exists(path) #路徑存在則返回True,路徑損壞返回False os.path.expanduser(path) #把path中包含的"~"和"~user"轉(zhuǎn)換成用戶目錄 os.path.expandvars(path) #根據(jù)環(huán)境變量的值替換path中包含的”$name”和”${name}” os.path.getatime(path) #返回最后一次進(jìn)入此path的時(shí)間。 os.path.getmtime(path) #返回在此path下最后一次修改的時(shí)間。 os.path.getctime(path) #返回path的大小 os.path.getsize(path) #返回文件大小,如果文件不存在就返回錯(cuò)誤 os.path.isabs(path) #判斷是否為絕對路徑 os.path.isfile(path) #判斷路徑是否為文件 os.path.isdir(path) #判斷路徑是否為目錄 os.path.islink(path) #判斷路徑是否為鏈接 os.path.ismount(path) #判斷路徑是否為掛載點(diǎn)() os.path.join(path1[, path2[, ...]]) #把目錄和文件名合成一個(gè)路徑 os.path.normcase(path) #轉(zhuǎn)換path的大小寫和斜杠 os.path.normpath(path) #規(guī)范path字符串形式 os.path.realpath(path) #返回path的真實(shí)路徑 os.path.relpath(path[, start]) #從start開始計(jì)算相對路徑 os.path.samefile(path1, path2) #判斷目錄或文件是否相同 os.path.sameopenfile(fp1, fp2) #判斷fp1和fp2是否指向同一文件 os.path.samestat(stat1, stat2) #判斷stat tuple stat1和stat2是否指向同一個(gè)文件 os.path.split(path) #把路徑分割成dirname和basename,返回一個(gè)元組 os.path.splitdrive(path) #一般用在windows下,返回驅(qū)動(dòng)器名和路徑組成的元組 os.path.splitext(path) #分割路徑,返回路徑名和文件擴(kuò)展名的元組 os.path.splitunc(path) #把路徑分割為加載點(diǎn)與文件 os.path.walk(path, visit, arg) #遍歷path,進(jìn)入每個(gè)目錄都調(diào)用visit函數(shù),visit函數(shù)必須有 3個(gè)參數(shù)(arg, dirname, names),dirname表示當(dāng)前目錄的目錄名,names代表當(dāng)前目錄下的所有文件名,args則為walk的第三個(gè)參數(shù) os.path.supports_unicode_filenames #設(shè)置是否支持unicode路徑名 在Linux和Mac平臺(tái)上,該函數(shù)會(huì)原樣返回path,在windows平臺(tái)上會(huì)將路徑中所有字符轉(zhuǎn)換為小寫,并將所有斜杠轉(zhuǎn)換為飯斜杠。 >>> os.path.normcase('c:/windows\\system32\\') 'c:\\windows\\system32\\' 規(guī)范化路徑,如..和/ >>> os.path.normpath('c://windows\\System32\\../Temp/') 'c:\\windows\\Temp' >>> a='/Users/jieli/test1/\\\a1/\\\\aa.py/../..' >>> print(os.path.normpath(a)) /Users/jieli/test1 1、os.walk() 方法用于通過在目錄樹中游走輸出在目錄中的文件名,向上或者向下。 格式:os.walk(top[, topdown=True[, οnerrοr=None[, followlinks=False]]]) top -- 是你所要遍歷的目錄的地址, 返回的是一個(gè)三元組(root,dirs,files)。root 所指的是當(dāng)前正在遍歷的這個(gè)文件夾的本身的地址dirs 是一個(gè) list ,內(nèi)容是該文件夾中所有的目錄的名字(不包括子目錄)files 同樣是 list , 內(nèi)容是該文件夾中所有的文件(不包括子目錄) topdown --可選,為 True,則優(yōu)先遍歷 top 目錄,否則優(yōu)先遍歷 top 的子目錄 (默認(rèn)為開啟)。如果 topdown 參數(shù)為 True,walk 會(huì)遍歷top文件夾,與top 文件夾中每一個(gè)子目錄。 onerror -- 可選,需要一個(gè) callable 對象,當(dāng) walk 需要異常時(shí),會(huì)調(diào)用。 followlinks -- 可選,如果為 True,則會(huì)遍歷目錄下的快捷方式(linux 下是軟連接 symbolic link )實(shí)際所指的目錄(默認(rèn)關(guān)閉),如果為 False,則優(yōu)先遍歷 top 的子目錄。import os for root, dirs, files in os.walk(".", topdown=False):for name in files:print(os.path.join(root, name))for name in dirs:print(os.path.join(root, name)) 運(yùn)行結(jié)果: ./.bash_logout ./amrood.tar.gz ./.emacs ./httpd.conf ./www.tar.gz ./mysql.tar.gz ./test.py ./.bashrc ./.bash_history ./.bash_profile ./tmp ./tmp/test.py walk函數(shù)的使用?
?五、sys模塊
? sys是與Python解釋器交互
1、sys.argv? ? ?命令行參數(shù)List,第一個(gè)元素是程序本身路徑
這個(gè)time.py文件的內(nèi)容如下:
?
不難看出這個(gè)程序,把我們在外部傳入的post傳入在這個(gè)sys.argv中且是個(gè)列表,當(dāng)然傳入的參數(shù)個(gè)數(shù)任意多。對其進(jìn)行改進(jìn)! import sys# print(sys.argv)def updata():print('上傳!!!')def download():print('download……')if sys.argv[1] == 'post':updata() elif sys.argv[1] =='download':download()
?
?結(jié)果:
?
import syssys.argv # 命令行參數(shù)List,第一個(gè)元素是程序本身路徑sys.exit(n) # 退出程序,正常退出時(shí)exit(0) n 為其他數(shù)時(shí),都存在其他異常退出,顯示1print(sys.version) # 獲取Python解釋程序的版本信息 # sys.maxint # 最大的Int值print(sys.path ) # 返回模塊的搜索路徑,初始化時(shí)使用PYTHONPATH環(huán)境變量的值 會(huì)查找環(huán)境變量,當(dāng)然最開始是從就近的工作文件找sys.path.append() # 可以添加查找給出的絕對目錄,添加到列表中 print(sys.platform) # 返回操作系統(tǒng)平臺(tái)名稱 # win32 或則 linuxsys.stdout.write('#') # 向終端打印標(biāo)準(zhǔn)化輸出 print就是用這個(gè)方法做出來的
sys.moudles # 是一個(gè)全局字典,該字典是python啟動(dòng)后就加載在內(nèi)存中。每當(dāng)程序員導(dǎo)入新的模塊,sys.modules將自動(dòng)記錄該模塊
?進(jìn)度條打印實(shí)例:
import sys import time import randomdef progress(percent, width=50):if percent >= 1:percent = 1 # 百分比保證100%show_str = ('[%%-%ds]'%width)%(int(width*percent)*'#')print('\r%s %d%%'%(show_str,int(100*percent)),file=sys.stdout,flush=True,end='')data_size = 1025 recv_size = 0 while recv_size < data_size:s = random.random()time.sleep(s) # 模擬數(shù)據(jù)的傳輸延遲recv_size += 50 # 每次收1024 percent = recv_size/data_size # 接收的比例progress(percent,width=70)import sys import time import randomdef progress(percent, width=50):if percent >= 1:percent = 1 # 百分比保證100%show_str = ('[%%-%ds]'%width)%(int(width*percent)*'#')print('\r%s %d%%'%(show_str,int(100*percent)),file=sys.stdout,flush=True,end='')data_size = 1025 recv_size = 0 while recv_size < data_size:s = random.random()time.sleep(s) # 模擬數(shù)據(jù)的傳輸延遲recv_size += 50 # 每次收1024 percent = recv_size/data_size # 接收的比例progress(percent,width=70)?
補(bǔ)充print知識(shí)點(diǎn):
print()函數(shù)的參數(shù)如下:print(*values, sep=' ', end='\n', file=sys.stdout, flush=False)1、 *values : 表示要打印的值 表示任何多個(gè)無名參數(shù), 各個(gè)值之間用‘,’(逗號(hào)隔開),打印出來各個(gè)值之間用空格隔開2、sep=’ ‘: 表示當(dāng)輸入多個(gè)打印的值時(shí),各個(gè)值之間分割方式, 默認(rèn)空格,可以自定義例:print('a','m','c',sep='\n') # a m c 換行3、 end=‘\n’**: 控制print中傳入值輸出完后結(jié)束符號(hào),默認(rèn)換行,這里可以設(shè)置為其他,如 ‘\t’, ’ ’ 等等, 可以自己定義例:print('python', end=' ')print('is good') # python is good4、file=sys.stdout:設(shè)置輸出設(shè)備,及把print中的值打印到什么地方,默認(rèn)輸出到準(zhǔn)端,可以設(shè)置file= 文件儲(chǔ)存對象,把內(nèi)容存到該文件中例:f = open(r'a.txt', 'w')print('python is good', file=f)f.close()# 則把python is good保存到 a.txt 文件中5、flush=False: 該參數(shù)主要是刷新, 默認(rèn)False,不刷新,Ture時(shí)刷新,例如在上面?4?中print中設(shè)置:
f = open(r'a.txt', 'w')
print('python is good', file=f, flush=True) # print到f中的內(nèi)容先從到內(nèi)存中,
當(dāng)文件對象關(guān)閉時(shí)才把內(nèi)容輸出到 a.txt 中,當(dāng)flush=True時(shí)它會(huì)立即把內(nèi)容刷新存到 a.txt 中
?
六、序列化模塊json、pickle、shelve簡述
什么叫序列化——將由原來的字典、列表等內(nèi)容轉(zhuǎn)換成一個(gè)字符串的過程就叫做序列化,反序列化就是將字符串或則字節(jié)轉(zhuǎn)化成原先的數(shù)據(jù)類型。
序列化的目的;
1、以某種存儲(chǔ)形式使自定義對象持久化;
2、將對象從一個(gè)地方傳遞到另一個(gè)地方;
3、使程序更具有維護(hù).
# a發(fā)送以一個(gè)數(shù)據(jù)給b,由于發(fā)送數(shù)據(jù),必須是二進(jìn)制。所以需要經(jīng)歷編碼到解碼的過程 dic = {'a':(1,2,3)} s = str(dic).encode(encoding='utf-8') # 編碼 ret = s.decode(encoding='utf-8') # 解碼 print(ret) # 查看數(shù)據(jù) print(type(ret)) # 查看類型 print(type(eval(ret))) # 還原為字典 eval將字符串轉(zhuǎn)換為字典# 結(jié)果: {'a': (1, 2, 3)} <class 'str'> <class 'dict'>使用eval不安全,有可能是病毒,接收方,啪的一些,就執(zhí)行了。這個(gè)時(shí)候,就需要用到序列化了如上圖,可知:
dic? ? ? ? -->? 字符串 序列化
字符串? -->? dic 反序列化
序列化? ==? 創(chuàng)造一個(gè)序列? ==》 創(chuàng)造一個(gè)字符串
實(shí)例化? ==? 創(chuàng)造一個(gè)實(shí)例
?
在Python中的序列化模塊:
? ?json? ??所有的編程語言都通用的序列化格式
它支持的數(shù)據(jù)類型非常有限 數(shù)字 字符串 列表 字典。
pickle? ? ? ???只能在python語言的程序之間傳遞數(shù)據(jù)用的
pickle支持python中所有的數(shù)據(jù)類型。
shelve? python3.* 之后才有的,可以把它當(dāng)作字典處理。
?
七、Json模塊
Json模塊提供四個(gè)功能:dumps、dump、loads、load,除了可以序列化字典還可以序列化列表等。注意Json操作的是字符串,所以在打開讀寫文件的時(shí)候使用‘w'和’r‘模式。
序列化(dumps,dump)
import json # 導(dǎo)入模塊 dic = {"慕容美雪":(170,60,'賞花')} # 鍵必須加雙引號(hào) ret = json.dumps(dic) # 序列化 print(type(dic),dic) # 查看原始數(shù)據(jù)類型 print(type(ret),ret) # 查看序列化后的數(shù)據(jù)<class 'dict'> {'慕容美雪': (170, 60, '賞花')} <class 'str'> {"\u6155\u5bb9\u7f8e\u96ea": [170, 60, "\u8d4f\u82b1"]}從結(jié)果中,可以看出: 原始數(shù)據(jù)類型是字典,序列化之后,就是字符串類型。而且中文變成了看不懂的字符串。 這是因?yàn)閖son.dumps 序列化時(shí)對中文默認(rèn)使用的ascii編碼。 想輸出真正的中文需要指定ensure_ascii=Falseimport json # 導(dǎo)入模塊 dic = {"慕容美雪":(170,60,'賞花')} ret = json.dumps(dic,ensure_ascii=False) # 序列化時(shí),不使用ascii碼 print(type(dic),dic) # 查看原始數(shù)據(jù)類型 print(type(ret),ret) # 查看序列化后的數(shù)據(jù)<class 'dict'> {'慕容美雪': (170, 60, '賞花')} <class 'str'> {"慕容美雪": [170, 60, "賞花"]}由于json不識(shí)別元組,json認(rèn)為元組和列表是一回事,所以變成了列表。 在json中,引號(hào),統(tǒng)一使用雙引號(hào)反序列化 (loads,load)
import json # 導(dǎo)入模塊 dic = {"慕容美雪":(170,60,'賞花')} ret = json.dumps(dic,ensure_ascii=False) # 序列化時(shí),不使用ascii碼 res = json.loads(ret) # 反序列化 print(type(res),res) # 查看反序列化后的數(shù)據(jù) 執(zhí)行輸出:<class 'dict'> {'慕容美雪': [170, 60, '賞花']}從結(jié)果中,可以看出,原來的單引號(hào)由還原回來了。 反序列化,比eval要安全。所以eval盡量少用。?
注意: dump和load是直接將對象序列化之后寫入文件,且依賴一個(gè)文件句柄。而dumps和loads是直接在文件中進(jìn)行操作,當(dāng)然可以可以通過文件的‘w'模式寫入。
dump 將序列化內(nèi)容寫入文件 import json # 導(dǎo)入模塊 dic = {"慕容美雪":(170,60,'賞花')} f = open('美雪','w',encoding='utf-8') json.dump(dic,f) # 先接收要序列化的對象,再接收文件句柄 f.close()執(zhí)行程序,查看文件美雪內(nèi)容為: {"\u6155\u5bb9\u7f8e\u96ea": [170, 60, "\u8d4f\u82b1"]} 要想文件寫入中文,可以加參數(shù)ensure_ascii=Falseimport json # 導(dǎo)入模塊 dic = {"慕容美雪":(170,60,'賞花')} f = open('美雪','w',encoding='utf-8') json.dump(dic,f,ensure_ascii=False) # 先接收要序列化的對象,再接收文件句柄 f.close()執(zhí)行程序,再次查看文件內(nèi)容:{"慕容美雪": [170, 60, "賞花"]}load 讀取文件中的序列化內(nèi)容import json # 導(dǎo)入模塊 dic = {"慕容美雪":(170,60,'賞花')} f = open('美雪','r',encoding='utf-8') ret = json.load(f) #接收文件句柄 print(ret) # 查看內(nèi)容 print(type(ret)) # 查看變量類型 f.close() # 最后記得關(guān)閉文件句柄 執(zhí)行輸出:{'慕容美雪': [170, 60, '賞花']} <class 'dict'>
?其他參數(shù):
import json data = {'username':['李華','二愣子'],'sex':'male','age':16} json_dic2 = json.dumps(data,sort_keys=True,indent=4,separators=(',',':'),ensure_ascii=False) print(json_dic2)執(zhí)行輸出: {"age":16,"sex":"male","username":["李華","二愣子"] }參數(shù)說明:Skipkeys:默認(rèn)值是False,如果dict的keys內(nèi)的數(shù)據(jù)不是python的基本類型(str,unicode,int,long,float,bool,None),設(shè)置為False時(shí),就會(huì)報(bào)TypeError的錯(cuò)誤。此時(shí)設(shè)置成True,則會(huì)跳過這類key ensure_ascii:,當(dāng)它為True的時(shí)候,所有非ASCII碼字符顯示為\uXXXX序列,只需在dump時(shí)將ensure_ascii設(shè)置為False即可,此時(shí)存入json的中文即可正常顯示。)indent:應(yīng)該是一個(gè)非負(fù)的整型,如果是0就是頂格分行顯示,如果為空就是一行最緊湊顯示,否則會(huì)換行且按照indent的數(shù)值顯示前面的空白分行顯示,這樣打印出來的json數(shù)據(jù)也叫pretty-printed json separators:分隔符,實(shí)際上是(item_separator, dict_separator)的一個(gè)元組,默認(rèn)的就是(',’,’:’);這表示dictionary內(nèi)keys之間用","隔開,而KEY和value之間用":"隔開。sort_keys:將數(shù)據(jù)根據(jù)keys的值進(jìn)行排序。?寫入多行
import json dic1 = {"S":(170,60,'唱歌')} dic2 = {"H":(170,60,'唱歌')} dic3 = {"E":(170,60,'唱歌')} f = open('she','a',encoding='utf-8') f.write(json.dumps(dic1)+'\n') # 寫入一行內(nèi)容,注意,一定要加換行符 f.write(json.dumps(dic2)+'\n') f.write(json.dumps(dic3)+'\n') f.close() # 關(guān)閉文件句柄 執(zhí)行程序,查看文件she內(nèi)容:{"S": [170, 60, "\u5531\u6b4c"]} {"H": [170, 60, "\u5531\u6b4c"]} {"E": [170, 60, "\u5531\u6b4c"]}讀取多行
import json f = open('she','r',encoding='utf-8') for i in f:print(json.loads(i.strip())) f.close()執(zhí)行輸出:{'S': [170, 60, '唱歌']} {'H': [170, 60, '唱歌']} {'E': [170, 60, '唱歌']}總結(jié):
???dumps序列化 loads反序列化 只在內(nèi)存中操作數(shù)據(jù) 主要用于網(wǎng)絡(luò)傳輸 和多個(gè)數(shù)據(jù)與文件打交道
dump序列化 load反序列化 主要用于一個(gè)數(shù)據(jù)直接存在文件里—— 直接和文件打交道
?
?
八、Pickle模塊?
用于Python特有的類型和Python的數(shù)據(jù)類型間進(jìn)行轉(zhuǎn)換 。 pickle模塊提供了四個(gè)功能:dumps、dump(序列化,存)、loads(反序列化,讀)、load(不僅可以序列化字典、列表……還可以把Python中任意的數(shù)據(jù)類型序列化)
用法和json是一樣的 :? 注意的是Pickle模塊是基于字節(jié)操作,所以在讀寫的時(shí)候要用’wb‘和’rb'
dumps序列化:
import pickle dic = {(170,60,'唱歌'):"S"} print(pickle.dumps(dic))#執(zhí)行結(jié)果: b'\x80\x03}q\x00K\xaaK<X\x06\x00\x00\x00\xe5\x94\xb1\xe6\xad\x8cq\x01\x87q\x02X\x01\x00\x00\x00Sq\x03s.' 輸出結(jié)果是bytes類型的,區(qū)別于jsondump寫入文件 文件模式必須是帶b,因?yàn)樗莃ytes類型、import pickle dic = {(170,60,'唱歌'):"S"} f = open('s','wb') #使用dump必須以+b的形式打開文件,編碼不需要指定,因?yàn)槭莃ytes類型 pickle.dump(dic,f) f.close() # 注意要關(guān)閉文件句柄#執(zhí)行結(jié)果是一堆亂碼load 讀取文件內(nèi)容:
import pickle f = open('s','rb') # bytes類型不需要指定編碼 print(pickle.load(f)) f.close() # 注意要關(guān)閉文件句柄執(zhí)行結(jié)果: {(170, 60, '唱歌'): 'S'}dump寫入多行內(nèi)容和load讀取文件內(nèi)容:
import pickle dic1 = {"張靚穎":(170,60,'唱歌')} dic2 = {"張韶涵":(170,60,'唱歌')} dic3 = {"梁靜茹":(170,60,'唱歌')} f = open('singer','wb') pickle.dump(dic1,f) pickle.dump(dic2,f) pickle.dump(dic3,f) f.close()#執(zhí)行結(jié)果是一堆亂碼 load 讀取文件內(nèi)容 import pickle f = open('singer','rb') print(pickle.load(f)) print(pickle.load(f)) print(pickle.load(f)) print(pickle.load(f)) # 多讀取一行,就會(huì)報(bào)錯(cuò) f.close()但是輸出的結(jié)果如下
為了解決這個(gè)問題,需要用到while循環(huán)+try:
import pickle f = open('singer','rb') while True:try:print(pickle.load(f))except Exception: # 接收一切錯(cuò)誤break # 跳出循環(huán) f.close()執(zhí)行結(jié)果: {'張靚穎': (170, 60, '唱歌')} {'張韶涵': (170, 60, '唱歌')} {'梁靜茹': (170, 60, '唱歌')}總結(jié):
json? 在寫入多次dump的時(shí)候 不能對應(yīng)執(zhí)行多次load來取出數(shù)據(jù),pickle可以
json? 如果要寫入多個(gè)元素 可以先將元素dumps序列化,f.write(序列化+'\n')寫入文件
? 讀出元素的時(shí)候,應(yīng)該先按行讀文件,在使用loads將讀出來的字符串轉(zhuǎn)換成對應(yīng)的數(shù)據(jù)類型
?
注意:pickle還可以序列化一些類或者函數(shù)(json不能):
import pickle class A:def __init__(self,name,age):self.name=nameself.age=age a = A('alex',80) ret = pickle.dumps(a) # 序列化對象 print(ret) obj = pickle.loads(ret) # 反序列化 print(obj.__dict__) # 查看對象屬性<br>f.close() 執(zhí)行結(jié)果: b'\x80\x03c__main__\nA\nq\x00)\x81q\x01}q\x02(X\x04\x00\x00\x00nameq\x03X\x04\x00\x00\x00alexq\x04X\x03\x00\x00\x00ageq\x05KPub.' {'name': 'alex', 'age': 80}將對象a寫入文件: import pickle class A:def __init__(self,name,age):self.name=nameself.age=age a = A('alex',80) f = open('a','wb') obj = pickle.dump(a,f) f.close()執(zhí)行結(jié)果: 也是一堆亂碼假設(shè)是一款Python游戲,就可以將人物的屬性,寫入文件。再次登陸時(shí),就可以重新加載了,用pickle就比較方便了。
當(dāng)刪除一個(gè)類的時(shí)候(注釋代碼),再次讀取文件,就會(huì)報(bào)錯(cuò)
import pickle # class A: # def __init__(self,name,age): # self.name=name # self.age=age # a = A('alex',80) f = open('a','rb') obj = pickle.load(f) print(obj.__dict__) f.close()執(zhí)行報(bào)錯(cuò)AttributeError: Can't get attribute 'A' on <module '__main__' from 'E:/python_script/day25/test.py'> 提示找不到類A?
將對象反序列時(shí),必須保證該對象的類必須存在,否則讀取報(bào)錯(cuò)
再次打開注釋,執(zhí)行以下,就正常了
?
九、shelve模塊
?Shelve是對象持久化保存方法,將對象保存到文件里面,缺省(即默認(rèn))的數(shù)據(jù)存儲(chǔ)文件是二進(jìn)制的。可以作為一個(gè)簡單的數(shù)據(jù)存儲(chǔ)方案。
注意shelve模塊中的key鍵必須是字符串形式,value可以是任意值。會(huì)同時(shí)打開三個(gè)文件。
使用方法:
1、shelve.open(filename, flag=’c’, protocol=None, writeback=False):? ? ? 創(chuàng)建或打開一個(gè)shelve對象。shelve默認(rèn)打開方式支持同時(shí)讀寫操作。
filename是關(guān)聯(lián)的文件路徑。可選參數(shù)flag:
1、默認(rèn)為‘c’:如果數(shù)據(jù)文件不存在,就創(chuàng)建,允許讀寫;可以是: ‘r’: 只讀;’w’: 可讀寫;
2、可以為‘n’: 每次調(diào)用open()都重新創(chuàng)建一個(gè)空的文件,可讀寫。
protocol:是序列化模式,默認(rèn)值為None。具體還沒有嘗試過,從pickle的資料中查到以下信息【protocol的值可以是1或2,表示以二進(jìn)制的形式序列化】
2、shelve.close()? ? ? #?同步并關(guān)閉shelve對象,注意每次使用完畢后都要關(guān)閉shelve對象,同樣可以使用with語句。
with shelve.open('spam') as db:db['eggs'] = 'eggs' with語句3、writeback:默認(rèn)為False。當(dāng)設(shè)置為True以后,shelf將會(huì)將所有從DB中讀取的對象存放到一個(gè)內(nèi)存緩存。
當(dāng)我們close()打開的shelf的時(shí)候,緩存中所有的對象會(huì)被重新寫入DB。writeback方式有優(yōu)點(diǎn)也有缺點(diǎn)(減少出錯(cuò)率,但是會(huì)增加內(nèi)存開銷)。
代碼示范:
# 1.創(chuàng)建一個(gè)shelf對象,直接使用open函數(shù)即可import shelve s = shelve.open('test_shelf.db') # try:s['kk'] = {'int': 10, 'float': 9.5, 'String': 'Sample data'}s['MM'] = [1, 2, 3] finally:s.close()# 2.如果想要再次訪問這個(gè)shelf,只需要再次shelve.open()就可以了,然后我們可以像使用字典一樣來使用這個(gè)shelfimport shelve try:s = shelve.open('test_shelf.db')value = s['kk']print(value) finally:s.close()# 3.對shelf對象,增、刪、改操作import shelve s = shelve.open('test_shelf.db', flag='w', writeback=True) try:# 增加s['QQQ'] = 2333# 刪除del s['MM']# 修改s['kk'] = {'String': 'day day up'} finally:s.close()# 注意:flag設(shè)置為‘r’-只讀模式,當(dāng)程序試圖去修改一個(gè)以只讀方式打開的DB時(shí),將會(huì)拋一個(gè)訪問錯(cuò)誤的異常。異常的具體類型取決于anydbm這個(gè)模塊在創(chuàng)建DB時(shí)所選用的DB。異常舉例:anydbm.error: need ‘c’ or ‘n’ flag to open new db# 4.循環(huán)遍歷shelf對象import shelve s = shelve.open('test_shelf.db') try:# 方法一:for item in s.items():print ('鍵[{}] = 值[{}]'.format(item[0], s[item[0]]))# 方法二:for key, value in s.items():print(key, value) finally:s.close()# 5.備注一個(gè)錯(cuò)誤: # open中的參數(shù)filename,起初認(rèn)為需要手動(dòng)新建一個(gè).db,或者.dat的文件,目前電腦中無任何真正的數(shù)據(jù)庫文件,所以采用了新建txt文件,修改后綴的方法創(chuàng)建.db,或者.dat的文件。 # 解釋器報(bào)錯(cuò),提示內(nèi)容為:"anydbm.error: db type could not be determined", # 原因是是filename已經(jīng)存在,并且格式與shelve不符,所以提示 “db type could not be determined”。 # 解決方法是,刪除該文件。首次運(yùn)行后會(huì)自動(dòng)生成該filename文件。 # 6.稍微復(fù)雜些的案例,實(shí)現(xiàn)一個(gè)簡單提問式的數(shù)據(jù)庫 shelve模塊代碼示例?
總結(jié):
1、shelve模塊比pickle模塊簡單,只有一個(gè)open函數(shù),返回類似字典的對象,可讀可寫;2、key必須為字符串,而值可以是python所支持的數(shù)據(jù)類型3、shelve模塊(**)------可以當(dāng)做數(shù)據(jù)庫用,以后基本不會(huì)用,(可以很方面的往文件中寫數(shù)據(jù)類型和讀) import shelve #存取很方便(可以做一個(gè)簡單的數(shù)據(jù)存儲(chǔ)方案) f=shelve.open(r'sheve.txt') f['stu1_info']={'name':'egon','age':18,'hobby':['piao','smoking','drinking']} #存 f['stu2_info']={'name':'gangdan','age':53} f['school_info']={'website':'http://www.pypy.org','city':'beijing'} print(f['stu1_info']['hobby']) f.close()import shelve d=shelve.open(r'a.txt') #生成三個(gè)文件分別是:a.txt.bak\a.txt.dat\a.txt.dir d['tom']={'age':18,'sex':'male'} #存的時(shí)候會(huì)生成三個(gè)文件,不用管,是python的一種處理機(jī)制 print(d['tom']['sex']) #可以取出字典中的key對應(yīng)的value print(d['tom']) #取出tom對應(yīng)的字典 d.close()import shelve d=shelve.open(r'a.txt',writeback=True) #writeback=True,對子字典修改完后要寫回,否則不會(huì)看到修改后的結(jié)果 d['egon']={'age':18,'sex':'male'} #存的時(shí)候會(huì)生成三個(gè)文件,不用管,是python的一種處理機(jī)制 d['egon']['age']=20 #將年齡修改為20 print(d['egon']['age']) #此時(shí)拿到的是修改后的年齡 print(d['egon']['sex']) d.close()
?
轉(zhuǎn)載于:https://www.cnblogs.com/double-W/p/9599232.html
總結(jié)
以上是生活随笔為你收集整理的time、random以及序列化模块的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 各种标志位的含义
- 下一篇: ldap配置系列二:jenkins集成l