Lesson_8
【8】對(duì)序列的文件操作:泡菜(pickle)
文件的寫(xiě)入只能寫(xiě)入普通的字符,對(duì)于list、tuple、dict、set這些類(lèi)型無(wú)法寫(xiě)入,所以只能使用二進(jìn)制寫(xiě)入,但是‘wb’使用了以后一直在報(bào)錯(cuò)TypeError: write() argument must be str, not tuple
那怎么辦:
python給我們提供了pickle模塊,它幾乎可以把所有python的對(duì)象轉(zhuǎn)化為二進(jìn)制的形式存放,這個(gè)過(guò)程稱(chēng)為picking,那么二進(jìn)制轉(zhuǎn)換為對(duì)象就是unpicking.
python的pickle模塊實(shí)現(xiàn)了基本的數(shù)據(jù)序列和反序列化。通過(guò)pickle模塊的序列化操作我們能夠?qū)⒊绦蛑羞\(yùn)行的對(duì)象信息保存到文件中去,永久存儲(chǔ);通過(guò)pickle模塊的反序列化操作,我們能夠從文件中創(chuàng)建上一次程序保存的對(duì)象。
基本接口:
pickle.dump(obj, file, [,protocol])
注解:將對(duì)象obj保存到文件file中去。
protocol為序列化使用的協(xié)議版本,0:ASCII協(xié)議,所序列化的對(duì)象使用可打印的ASCII碼表示;1:老式的二進(jìn)制協(xié)議;2:2.3版本引入的新二進(jìn)制協(xié)議,較以前的更高效。其中協(xié)議0和1兼容老版本的python。protocol默認(rèn)值為0。
file:對(duì)象保存到的類(lèi)文件對(duì)象。file必須有write()接口, file可以是一個(gè)以'w'方式打開(kāi)的文件或者一個(gè)StringIO對(duì)象或者其他任何實(shí)現(xiàn)write()接口的對(duì)象。如果protocol>=1,文件對(duì)象需要是二進(jìn)制模式打開(kāi)的。
pickle.load(file)
注解:從file中讀取一個(gè)字符串,并將它重構(gòu)為原來(lái)的python對(duì)象。
file:類(lèi)文件對(duì)象,有read()和readline()接口。
import pickle #引入數(shù)據(jù)持久性模塊
myList = (1,2,3,4,5,"sunck is a good man")
path = r"C:\Users\xlg\Desktop\Python-1704\day08\1-文件讀寫(xiě)\file6.txt"
f = open(path, "wb")
pickle.dump(myList, f)
f.close()
#讀取
f1 = open(path, "rb")
tempList= pickle.load(f1)
print(tempList)
f1.close()
【9】編碼和解碼
如果中文字符在寫(xiě)入文件的時(shí)候沒(méi)有設(shè)置utf-8
或者gbk
、gb2312
等中文字符集,那么讀取的時(shí)候就是2進(jìn)制的。
path = 'wdemo.txt'
with open(path, "wb") as f1:
str = "你好上海,你好千鋒"
f1.write(str.encode("utf-8"))
with open(path, "rb") as f2:
data = f2.read()
print(data)
print(type(data))
newData = data.decode("utf-8")
print(newData)
print(type(newData))
【10】文件系統(tǒng)(os模塊)
接下來(lái)我們講一個(gè)Python里面十分有用的模塊,什么是模塊?其實(shí)我們每一個(gè).py的文件都是一個(gè)模塊。python自身帶有非常多使用的模塊,在日常編程中,如果能夠熟練地掌握它們,將事半功倍。
首先要介紹的高大上的OS模塊,OS就是Operating System的縮寫(xiě),意思是操作系統(tǒng)。很多的文件系統(tǒng)的訪問(wèn)都是通過(guò)OS模塊來(lái)實(shí)現(xiàn)的。我們所知道的windows、Mac OS、UNIX、Linux等,對(duì)于這些系統(tǒng)的底層實(shí)現(xiàn)起來(lái)也是不一樣的,因此你就需要考慮用到哪個(gè)模塊了。
但是python是跨平臺(tái)的語(yǔ)言,也就是說(shuō),同樣的源碼在不同的操作系統(tǒng)不需要修改同樣可以實(shí)現(xiàn)。有了OS模塊,不需要關(guān)心什么操作系統(tǒng)下使用什么模塊,OS會(huì)幫你選擇正確的模塊并調(diào)用。
函數(shù)名 | 使用方法 |
---|---|
os.getcwd() | 獲得當(dāng)前工作目錄 |
os.curdir | 返回當(dāng)前目錄('.') |
os.environ | 獲取當(dāng)前環(huán)境變量 |
os.environ.get(path) | 獲取指定的環(huán)境變量 |
os.listdir(path): | 列出dirname下的目錄和文件 |
os.mkdir(path): | 創(chuàng)建單層目錄,如果目錄已經(jīng)存在拋出異常 |
os.makedirs(.path) | 遞歸創(chuàng)建多級(jí)目錄,如果目錄已經(jīng)存在拋出異常(E:\a\b和E:\a\c不會(huì)沖突) |
os.remove(path) | 刪除文件 |
os.rmdir(path) | 刪除單層目錄,如果目錄非空則拋出異常 |
os.removedirs(path) | 遞歸刪除目錄,從子目錄到父目錄逐個(gè)刪除,遇到目錄非空則拋出異常 |
os.rename(new,old) | 將文件的old重命名為new |
os.system(command) | 運(yùn)行系統(tǒng)的shell命令 |
以下是: | 支持路徑操作中常用到的一些定義支持所有平臺(tái) |
os.curdir | 指代當(dāng)前目錄('.') |
os.pardir | 指代上一級(jí)目錄('..') |
os.sep | 輸出操作系統(tǒng)特定的路徑分隔符(windons下是\,linux下是/) |
os.linesp | 當(dāng)前平臺(tái)使用的終止符((windons下是\r\n,linux下是\n) |
os.name | 指定當(dāng)前的操作系統(tǒng)(包括'posix','nt','mac','os2','ce','java') |
1.getcwd()
得當(dāng)前工作目錄
import os
print(os.getcwd())
#C:\\Python36
2.chdir()
改變工作目錄
import os
os.chdir('C:\\Python27')
print(os.getcwd())
#C:\\Python27
3、system()
運(yùn)行系統(tǒng)命令
import os
os.system('clear') #清理命令行屏幕上的所有過(guò)去輸入的信息
4、walk()
非常有用的函數(shù),可以用來(lái)指定遍歷指定路徑下的所有子目錄,并返回一個(gè)三元祖的結(jié)果:
import os
for i in os.walk('/Users/ruidong/www'):
print(i)
5.os.path模塊
這是另一個(gè)強(qiáng)大的模塊,它可以完成一些路徑操作。
函數(shù)名 | 使用方法 |
---|---|
os.path.abspath(path) | #返回絕對(duì)路徑 |
os.path.basename(path) | #返回文件名 |
os.path.dirname(path) | #返回文件路徑 |
os.path.join(path1[, path2[, ...]]) | #把目錄和文件名合成一個(gè)路徑 |
os.path.split(path) | #把路徑分割成dirname和basename,返回一個(gè)元組 |
os.path.splitext(path) | #分割路徑,返回路徑名和文件擴(kuò)展名的元組 |
os.path.getsize(path) | #返回文件大小,如果文件不存在就返回錯(cuò)誤 |
os.path.getatime(path) | #返回最后一次訪問(wèn)的時(shí)間。 |
os.path.getctime(path) | #返回文件的創(chuàng)建時(shí)間 |
os.path.getmtime(path) | #返回在此path下最后一次修改的時(shí)間。 |
以下函數(shù)返回的是 | True或False |
os.path.exists(path) | #路徑存在則返回True,否則回False |
os.path.samefile(path1, path2) | #判斷兩個(gè)變量是不是指向同一個(gè)文件 |
os.path.isabs(path) | #判斷指定路徑是否是絕對(duì)路徑 |
os.path.isdir(path) | #判斷指定路徑是否存在且是個(gè)目錄 |
os.path.isfile(path) | #判斷指定路徑是否存在且是個(gè)文件 |
os.path.islink(path) | #判斷指定路徑是否存在且是一個(gè)符號(hào)鏈接 |
os.path.ismount(path) | #判斷指定目錄是否存在且是個(gè)掛載點(diǎn) |
os.path.join()
這里的join和BIF里面的join不是一回事,它是將路徑名和文件名組合成一個(gè)完整的路徑。
import os
_path = r'/Users/ruidong/www'
_file = r'demo.txt'
final_path = os.path.join(_path,_file)
print(final_path)
#/Users/ruidong/www/demo.txt
split()和splitext()
split()和splitext()函數(shù)都用于分割路勁,split()函數(shù)分割路徑和文件名,而splitext()用于分割文件名和后綴名。
import os
_path = r'/Users/ruidong/www/demo.txt'
print(os.path.split(_path))
print(os.path.splitext(_path))
#('/Users/ruidong/www', 'demo.txt')
#('/Users/ruidong/www/demo', '.txt')
【11】棧和隊(duì)列
collections是Python內(nèi)建的一個(gè)集合模塊,提供了許多有用的集合類(lèi)。
使用list存儲(chǔ)數(shù)據(jù)時(shí),按索引訪問(wèn)元素很快,但是插入和刪除元素就很慢了,因?yàn)閘ist是線性存儲(chǔ),數(shù)據(jù)量大的時(shí)候,插入和刪除效率很低。
deque是為了高效實(shí)現(xiàn)插入和刪除操作的雙向列表,適合用于隊(duì)列和棧:
棧
棧(stack)又名堆棧,它是一種運(yùn)算受限的線性表。其限制是僅允許在表的一端進(jìn)行插入和刪除運(yùn)算。這一端被稱(chēng)為棧頂,相對(duì)地,把另一端稱(chēng)為棧底。向一個(gè)棧插入新元素又稱(chēng)作進(jìn)棧、入棧或壓棧,它是把新元素放到棧頂元素的上面,使之成為新的棧頂元素;從一個(gè)棧刪除元素又稱(chēng)作出棧或退棧,它是把棧頂元素刪除掉,使其相鄰的元素成為新的棧頂元素。
棧的原則就是先進(jìn)后出
<image src='images/stack.jpg' />
我們用一個(gè)列表來(lái)模擬壓棧:
我們列表的最后一個(gè)元素就是棧頂
第一個(gè)元素就是棧底
#用隊(duì)列集合模擬棧運(yùn)行
import collections
#創(chuàng)建一個(gè)隊(duì)列 ,用于模擬棧的運(yùn)行
queue = collections.deque()
print(queue)
#進(jìn)棧(存數(shù)據(jù))
queue.append("A")
print(queue)
queue.append("B")
print(queue)
queue.append("C")
print(queue)
#出棧(取數(shù)據(jù))
res1 = queue.pop()
print("res1 =", res1)
print(queue)
res2 = queue.pop()
print("res2 =", res2)
print(queue)
res3 = queue.pop()
print("res3 =", res3)
print(queue)
隊(duì)列
隊(duì)列是一種特殊的線性表,特殊之處在于它只允許在表的前端(front)進(jìn)行刪除操作,而在表的后端(rear)進(jìn)行插入操作,和棧一樣,隊(duì)列是一種操作受限制的線性表。進(jìn)行插入操作的端稱(chēng)為隊(duì)尾,進(jìn)行刪除操作的端稱(chēng)為隊(duì)頭。
它的原則是先進(jìn)先出
<image src='images/deque.png' />
import collections
#創(chuàng)建一個(gè)隊(duì)列
queue = collections.deque()
print(queue)
#進(jìn)隊(duì)(存數(shù)據(jù))
queue.append("A")
print(queue)
queue.append("B")
print(queue)
queue.append("C")
print(queue)
#出隊(duì)(取數(shù)據(jù))
res1 = queue.popleft()
print("res1 =", res1)
print(queue)
res2 = queue.popleft()
print("res2 =", res2)
print(queue)
res3 = queue.popleft()
print("res3 =", res3)
print(queue)
我們的棧和隊(duì)列了其實(shí)就是學(xué)習(xí)一種思想,包裹之前的遞歸都是一中程序的思想
課堂小案例,結(jié)合文件
遍歷目錄
import os
def getALlDir(path,sp = ' '):
filesList = os.listdir(path)
sp += ' '
for fileName in filesList:
filesAbsPath = os.path.join(path, fileName)
if os.path.isdir(filesAbsPath):
print(sp + '目錄:',fileName)
getALlDir(filesAbsPath,sp)
else:
print(sp + '文件:',fileName)
getALlDir(r'/Users/ruidong/PycharmProjects')
Time
【1】時(shí)間可以改變一切:time模塊
在我們平常的代碼中,經(jīng)常需要和時(shí)間打交道。在Python中,與時(shí)間處理相關(guān)的模塊有:time、datetime以及calendar。學(xué)會(huì)計(jì)算時(shí)間,對(duì)程序的調(diào)優(yōu)非常重要,可以在程序中狂打時(shí)間戳,來(lái)具體判斷程序中哪一塊耗時(shí)最多,從而找到程序調(diào)優(yōu)的重心處。這里先來(lái)講一個(gè)time模塊。
在開(kāi)始前,先說(shuō)明幾點(diǎn):
1、在Python中,通常有這幾種方式表示時(shí)間:時(shí)間戳、格式化的時(shí)間字符串、元組(struct_time 共九種元素)。由于Python的time模塊主要是調(diào)用C庫(kù)實(shí)現(xiàn)的,所以在不同的平臺(tái)可能會(huì)有所不同。
2、時(shí)間戳(timestamp)的方式:時(shí)間戳表示是從1970年1月1號(hào) 00:00:00開(kāi)始到現(xiàn)在按秒計(jì)算的偏移量。查看一下type(time.time())的返回值類(lèi)型,可以看出是float類(lèi)型。返回時(shí)間戳的函數(shù)主要有time()、clock()等。
3、UTC(世界協(xié)調(diào)時(shí)),就是格林威治天文時(shí)間,也是世界標(biāo)準(zhǔn)時(shí)間。在中國(guó)為UTC+8。DST(夏令時(shí)):是一種節(jié)約能源而人為規(guī)定時(shí)間制度,在夏季調(diào)快1個(gè)小時(shí)。
4、元組方式:struct_time元組共有9個(gè)元素,返回struct_time的函數(shù)主要有g(shù)mtime(),localtime(),strptime()。
使用該模塊中的函數(shù)時(shí),必須先引入該模塊(import time)
1、時(shí)間戳
python中的時(shí)間戳是以秒為單位的,它是一個(gè)浮點(diǎn)類(lèi)型的數(shù)據(jù)。
import time
#時(shí)間戳
print(time.time())
#毫秒時(shí)間戳,
print(time.time() * 1000)
#毫秒時(shí)間戳取整
print(int(time.time() * 1000))
#1510884320.13084
#1510884320130.936
#1510884320130
2、struct_time元祖結(jié)構(gòu)格式
time.localtime(secs)
將一個(gè)時(shí)間戳轉(zhuǎn)換為當(dāng)前時(shí)區(qū)的struct_time,即時(shí)間數(shù)組格式的時(shí)間
如果secs參數(shù)未提供,則以當(dāng)前時(shí)間為準(zhǔn)(即會(huì)默認(rèn)調(diào)用time.time())。
#沒(méi)有傳入?yún)?shù)
import time
print(time.localtime())
#time.struct_time(tm_year=2017, tm_mon=11, tm_mday=17, tm_hour=10, tm_min=14, tm_sec=2, tm_wday=4, tm_yday=321, tm_isdst=0)
#傳入?yún)?shù)的
import time
out_time = time.time() - (60 * 60 * 24 * 365 *2)
print(int(out_time))
print(time.localtime(1447812614))
#1447812789
#time.struct_time(tm_year=2015, tm_mon=11, tm_mday=18, tm_hour=10, tm_min=10, tm_sec=14, tm_wday=2, tm_yday=322, tm_isdst=0)
3、將一個(gè)時(shí)間戳轉(zhuǎn)換為UTC時(shí)區(qū)的struct_time
time.gmtime([secs])
time.gmtime() 函數(shù)將一個(gè)時(shí)間戳轉(zhuǎn)換為UTC時(shí)區(qū)(0時(shí)區(qū))的struct_time,可選的參數(shù)sec表示從1970-1-1 00:00:00以來(lái)的秒數(shù)。其默認(rèn)值為time.time(),函數(shù)返回time.struct_time類(lèi)型的對(duì)象。(struct_time是在time模塊中定義的表示時(shí)間的對(duì)象)。
如果secs參數(shù)未提供,則以當(dāng)前時(shí)間為準(zhǔn)。
sec – 轉(zhuǎn)換為time.struct_time類(lèi)型的對(duì)象的秒數(shù)
#注意它是0時(shí)區(qū),就是說(shuō)比我們的時(shí)間少了8個(gè)小時(shí)
import time
print(time.gmtime())
#time.struct_time(tm_year=2017, tm_mon=11, tm_mday=17, tm_hour=2, tm_min=18, tm_sec=12, tm_wday=4, tm_yday=321, tm_isdst=0)
4、time.mktime(t):將一個(gè)struct_time轉(zhuǎn)化為時(shí)間戳
time.mktime(t) 函數(shù)執(zhí)行與gmtime(), localtime()相反的操作,它接收struct_time對(duì)象作為參數(shù),返回用秒數(shù)表示時(shí)間的浮點(diǎn)數(shù)。
如果輸入的值不是一個(gè)合法的時(shí)間,將觸發(fā) OverflowError 或 ValueError。
參數(shù):
t – 結(jié)構(gòu)化的時(shí)間或者完整的9位元組元素
import time
print(time.mktime(time.localtime()))
#1510885313.0
5、讓程序睡一會(huì)
time.sleep(secs):線程推遲指定的時(shí)間運(yùn)行
線程睡眠指定時(shí)間,單位為妙。
secs:為數(shù)值類(lèi)型的整數(shù)或浮點(diǎn)數(shù)。
import time
for i in range(1,6):
print(i)
time.sleep(1)
#5秒以后觸發(fā)
print("節(jié)日快樂(lè)")
6、time.clock()
這個(gè)函數(shù), 函數(shù)以浮點(diǎn)數(shù)計(jì)算的秒數(shù)返回當(dāng)前的CPU時(shí)間。用來(lái)衡量不同程序的耗時(shí),比time.time()更有用。在不同的系統(tǒng)上含義不同。在NUix系統(tǒng)上,它返回的是“進(jìn)程時(shí)間”,它是用妙表示的浮點(diǎn)數(shù)(時(shí)間戳)。而在Windows中,第一次調(diào)用,返回的是進(jìn)程運(yùn)行時(shí)實(shí)際時(shí)間。而第二次之后的調(diào)用是自第一次調(diào)用以后到現(xiàn)在的運(yùn)行時(shí)間。
返回值
該函數(shù)有兩個(gè)功能:
(1)在第一次調(diào)用的時(shí)候,返回的是程序運(yùn)行的實(shí)際時(shí)間;
(2)第二次之后的調(diào)用,返回的是自第一次調(diào)用后,到這次調(diào)用的時(shí)間間隔在win32系統(tǒng)下,這個(gè)函數(shù)返回的是真實(shí)時(shí)間(wall time),而在Unix/Linux下返回的是CPU時(shí)間。
import time
print(time.clock())
print(time.clock())
#0.066535
#0.0666
7、time.asctime( [t] )
把一個(gè)表示時(shí)間的元組或者struct_time表示為 ‘Sun Aug 23 14:31:59 2015’ 這種形式。如果沒(méi)有給參數(shù),會(huì)將time.localtime()作為參數(shù)傳入。
參數(shù):
t – 9個(gè)元素的元組或者通過(guò)函數(shù) gmtime() 或 localtime() 返回的時(shí)間值
import time
local = time.localtime()
asc = time.asctime(local)
print(asc)
Fri Nov 17 10:41:46 2017
8、time.ctime([secs])
把一個(gè)時(shí)間戳(按秒計(jì)算的浮點(diǎn)數(shù))轉(zhuǎn)化為time.asctime()的形式。如果未指定參數(shù),將會(huì)默認(rèn)使用time.time()作為參數(shù)。它的作用相當(dāng)于time.asctime(time.localtime(secs))
參數(shù):
secs – 要轉(zhuǎn)換為字符串時(shí)間的秒數(shù)
import time
print(time.ctime())
#Fri Nov 17 10:44:43 2017
9、格式化時(shí)間
time.strftime( format [, t] )
返回字符串表示的當(dāng)?shù)貢r(shí)間。
把一個(gè)代表時(shí)間的元組或者struct_time(如由time.localtime()和time.gmtime()返回)轉(zhuǎn)化為格式化的時(shí)間字符串,格式由參數(shù)format決定。如果未指定,將傳入time.localtime()。如果元組中任何一個(gè)元素越界,就會(huì)拋出ValueError的異常。函數(shù)返回的是一個(gè)可讀表示的本地時(shí)間的字符串。
參數(shù):
format:格式化字符串
t :可選的參數(shù)是一個(gè)struct_time對(duì)象
%a 本地星期名稱(chēng)的簡(jiǎn)寫(xiě)(如星期四為T(mén)hu)
%A 本地星期名稱(chēng)的全稱(chēng)(如星期四為T(mén)hursday)
%b 本地月份名稱(chēng)的簡(jiǎn)寫(xiě)(如八月份為agu)
%B 本地月份名稱(chēng)的全稱(chēng)(如八月份為august)
%c 本地相應(yīng)的日期和時(shí)間的字符串表示(如:15/08/27 10:20:06)
%d 一個(gè)月中的第幾天(01 - 31)
%f 微秒(范圍0.999999)
%H 一天中的第幾個(gè)小時(shí)(24小時(shí)制,00 - 23)
%I 第幾個(gè)小時(shí)(12小時(shí)制,0 - 11)
%j 一年中的第幾天(001 - 366)
%m 月份(01 - 12)
%M 分鐘數(shù)(00 - 59)
%p 本地am或者pm的相應(yīng)符
%S 秒(00 - 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)日期字符串(如15/08/01)
%X 本地相應(yīng)時(shí)間字符串(如08:08:10)
%y 去掉世紀(jì)的年份(00 - 99)兩個(gè)數(shù)字表示的年份
%Y 完整的年份(4個(gè)數(shù)字表示年份)
%z 與UTC時(shí)間的間隔(如果是本地時(shí)間,返回空字符串)
%Z 時(shí)區(qū)的名字(如果是本地時(shí)間,返回空字符串)
%% ‘%’字符
import time
local_time = time.localtime()
format_time = time.strftime('%Y年%m月%d日 %H:%M:%S',local_time)
print(format_time)
#注意月份是小m(%m),分鐘是大M(%M)。年是大寫(xiě)
#2017年11月17日 10:51:10
你也可以玩拼接
import time
local_time = time.localtime()
print(str(local_time.tm_year) + "年" + str(local_time.tm_mon) + "月" + str(local_time.tm_mday) + "日")
#2017年11月17日
獲取當(dāng)前時(shí)間的時(shí)分秒
import time
local_time = time.localtime()
print(time.strftime('%H:%M:%S',local_time))
#10:55:44
獲取當(dāng)前時(shí)間的格式化時(shí)間
import time
t = time.localtime()
print(time.strftime('%F %T',t)) #簡(jiǎn)寫(xiě)
print(time.strftime('%Y-%m-%d %H:%M:%S %p',t)) # am 還是 pm
#2017-11-17 11:23:57
#2017-11-17 11:23:57 AM
10、將格式字符串轉(zhuǎn)化成struct_time.
time.strptime(string[,format])
該函數(shù)是time.strftime()函數(shù)的逆操作。time strptime() 函數(shù)根據(jù)指定的格式把一個(gè)時(shí)間字符串解析為時(shí)間元組。所以函數(shù)返回的是struct_time對(duì)象。
參數(shù):
string :時(shí)間字符串
format:格式化字符串
import time,datetime
#創(chuàng)建一個(gè)時(shí)間字符串變量stime
stime = "2015-08-24 13:01:30"
formattime = time.strptime(stime,"%Y-%m-%d %H:%M:%S")
print(formattime)
#遍歷返回的時(shí)間元組序列
for i in formattime :
print(i,end=' ')
#time.struct_time(tm_year=2015, tm_mon=8, tm_mday=24, tm_hour=13, tm_min=1, tm_sec=30, tm_wday=0, tm_yday=236, tm_isdst=-1)
#2015 8 24 13 1 30 0 236 -1
<font color='red'>注意:在使用strptime()函數(shù)將一個(gè)指定格式的時(shí)間字符串轉(zhuǎn)化成元組時(shí),參數(shù)format的格式必須和string的格式保持一致,如果string中日期間使用“-”分隔,format中也必須使用“-”分隔,時(shí)間中使用冒號(hào)“:”分隔,后面也必須使用冒號(hào)分隔,否則會(huì)報(bào)格式不匹配的錯(cuò)誤。</font>
【2】學(xué)會(huì)操控時(shí)間:datetime模塊
Python提供了多個(gè)內(nèi)置模塊用于操作日期時(shí)間,像calendar,time,datetime。time模塊我在之前的文章已經(jīng)有所介紹,它提供 的接口與C標(biāo)準(zhǔn)庫(kù)time.h基本一致。相比于time模塊,datetime模塊的接口則更直觀、更容易調(diào)用。今天就來(lái)講講datetime模塊。
datetime模塊定義了兩個(gè)常量:datetime.MINYEAR和datetime.MAXYEAR,分別表示datetime所能表示的最 小、最大年份。其中,MINYEAR = 1,MAXYEAR = 9999。(對(duì)于偶等玩家,這個(gè)范圍已經(jīng)足夠用矣~~)
datetime模塊定義了下面這幾個(gè)類(lèi):
datetime.date:表示日期的類(lèi)。常用的屬性有year, month, day;
datetime.time:表示時(shí)間的類(lèi)。常用的屬性有hour, minute, second, microsecond;
datetime.datetime:表示日期時(shí)間。
datetime.timedelta:表示時(shí)間間隔,即兩個(gè)時(shí)間點(diǎn)之間的長(zhǎng)度。
datetime.tzinfo:與時(shí)區(qū)有關(guān)的相關(guān)信息。(這里不詳細(xì)充分討論該類(lèi),感興趣的童鞋可以參考python手冊(cè))
今天我們講講datetime的基本的幾種方法:
1. 獲取當(dāng)前datetime
import datetime
print(datetime.datetime.now())
#2017-11-17 14:42:01.175940
2. 獲取當(dāng)天date
import datetime
print(datetime.date.today())
#2017-11-17
3. 獲取明天/前N天 /或者昨天
import datetime
print(datetime.date.today())
print(datetime.date.today() + datetime.timedelta(days=1))
print(datetime.date.today() + datetime.timedelta(days=-1))
print(datetime.date.today() - datetime.timedelta(days=1))
#2017-11-17
#2017-11-18
#2017-11-16
4、獲取當(dāng)天開(kāi)始和結(jié)束時(shí)間(00:00:00 23:59:59)
datetime.combine(date, time):根據(jù)date和time,創(chuàng)建一個(gè)datetime對(duì)象;
import datetime
print(datetime.datetime.combine(datetime.date.today(), datetime.time.min))
print(datetime.datetime.combine(datetime.date.today(), datetime.time.max))
print((str(datetime.datetime.combine(datetime.date.today(), datetime.time.max)).split('.'))[0]) #轉(zhuǎn)換成str類(lèi)型的舍去毫秒值
#2017-11-17 00:00:00
#2017-11-17 23:59:59.999999
#2017-11-17 23:59:59
5. 獲取兩個(gè)datetime的時(shí)間差
total_seconds()把兩時(shí)間集轉(zhuǎn)換成總秒數(shù)
print((datetime.datetime(2018,1,13,12,0,0) - datetime.datetime.now()).total_seconds())
#4912373.883664
6.關(guān)系轉(zhuǎn)換
datetime => string
import datetime
date_to_str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(date_to_str,type(date_to_str))
#22014-12-31 18:20:10 <class 'datetime.datetime'>
string => datetime
import datetime
str_to_date = datetime.datetime.strptime("2014-12-31 18:20:10", "%Y-%m-%d %H:%M:%S")
print(str_to_date,type(str_to_date))
#2014-12-31 18:20:10 <class 'datetime.datetime'>
datetime => timetuple (time.struct_time格式)
import datetime
date_to_timetuple = datetime.datetime.now().timetuple()
print(date_to_timetuple,type(date_to_timetuple))
#time.struct_time(tm_year=2017, tm_mon=11, tm_mday=17, tm_hour=16, tm_min=31, tm_sec=2, tm_wday=4, tm_yday=321, tm_isdst=-1) <class 'time.struct_time'>
timetuple => datetime
import datetime,time
now = time.localtime() #struct_time類(lèi)型
print(now)
now = time.strftime("%F %T",ls) #先轉(zhuǎn)成timestamp時(shí)間格式,轉(zhuǎn)成字符串
print(now,type(now))
now = datetime.datetime.strptime(now, "%Y-%m-%d %H:%M:%S")
print(now,type(now))
datetime => timestamp
import datetime,time
now = datetime.datetime.now()
timestamp = time.mktime(now.timetuple())
print(timestamp,type(timestamp))
#1510908711.0 <class 'float'>
timestamp => datetime
import datetime
datetime = datetime.datetime.fromtimestamp(1421077403.0)
print(datetime,type(datetime))
#2015-01-12 23:43:23 <class 'datetime.datetime'>
7. 獲取本周/本月/上月最后一天 和第一天
本周
date.weekday():返回weekday,如果是星期一,返回0;如果是星期2,返回1,以此類(lèi)推;
import datetime
today = datetime.date.today()
print(today)
one = today - datetime.timedelta(today.weekday())
print(one) #本周第一天
two = today + datetime.timedelta(6-today.weekday())
print(two) #本周最后一天
#2017-11-17
#2017-11-13
#2017-11-19
本月
cale是python的日歷模塊
calendar.monthrange(year,month)
返回兩個(gè)整數(shù)。第一個(gè)是該月的星期幾的日期碼,第二個(gè)是該月的日期碼。日從0(星期一)到6(星期日);月從1到12。
import calendar,datetime
today = datetime.date.today()
_,last_day_num = calendar.monthrange(today.year,today.month)
print(last_day_num)
last_day = datetime.date(today.year, today.month,last_day_num)
print(last_day)
#_,取可迭代序列的最后一個(gè)值,但是不能取中間的,舍棄如果是三個(gè)那么就是_,_,
#30
#2017-11-30
獲取上個(gè)月的最后一天
import datetime
today = datetime.date.today()
print(today)
first = datetime.date(day=1, month=today.month, year=today.year)
print(first)
lastMonth = first - datetime.timedelta(days=1)
print(lastMonth)
#2017-11-17
#2017-11-01
#2017-10-31
上個(gè)月的最好一天(跨年)
import datetime,time
today = datetime.datetime.strptime('2017-01-01',"%Y-%m-%d")
print(today)
first = datetime.date(day=1, month=today.month, year=today.year)
print(first)
lastMonth = first - datetime.timedelta(days=1)
print(lastMonth)
#2017-01-01 00:00:00
#2017-01-01
#2016-12-31
【3】時(shí)間的書(shū)籍:calendar(日歷模塊)
——————
1、日歷
ccalendar(year,w=2,l=1,c=6)
返回一個(gè)多行字符串格式的year年年歷,3個(gè)月一行,間隔距離為c。 每日寬度間隔為w字符。每行長(zhǎng)度為21* W+18+2* C。l是每星期行數(shù)。
import calendar
print(calendar.calendar(2017))
2、獲取每周的開(kāi)始值
firstweekday()
返回當(dāng)前每周起始日期的設(shè)置。默認(rèn)情況下,首次載入caendar模塊時(shí)返回0,即星期一。
import calendar
print(calendar.firstweekday())
#0
3、判斷是否是潤(rùn)年
calendar.isleap(year)
是閏年返回True,否則為false。
<font color='red'>注意:只能是整數(shù),否則會(huì)報(bào)錯(cuò)</font>
import calendar
print(calendar.isleap(2020))
#True
4、返回在兩個(gè)年數(shù)時(shí)間軸之間的閏年總數(shù)。
calendar.leapdays(y1,y2)
返回在Y1,Y2兩年之間的閏年總數(shù)。
import calendar
print(calendar.leapdays(-1000,2017))
#732
5、返回指定月的日歷
calendar.month(year,month,w=2,l=1)
返回一個(gè)多行字符串格式的year年month月日歷,兩行標(biāo)題,一周一行。每日寬度間隔為w字符。每行的長(zhǎng)度為7* w+6。l是每星期的行數(shù)。
import calendar
print(calendar.month(2017,11))
6、返回指定月的瑞列表
calendar.monthcalendar(year,month)
返回一個(gè)整數(shù)的單層嵌套列表。每個(gè)子列表裝載代表一個(gè)星期的整數(shù)。Year年month月外的日期都設(shè)為0;范圍內(nèi)的日子都由該月第幾日表示,從1開(kāi)始。
import calendar
print(calendar.monthcalendar(2017,11) )
#[[0, 0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26], [27, 28, 29, 30, 0, 0, 0]]
7、返回指定月的最后一天的星期碼和日期碼
calendar.monthrange(year,month)
返回一個(gè)元祖。第一個(gè)是該月的星期幾的日期碼,第二個(gè)是該月的最后一天日期碼。日從0(星期一)到6(星期日);月從1到12。
import calendar
time1 = calendar.monthrange(2017,11)
print(time1,type(time1))
#(2, 30) <class 'tuple'>
8、返回指定日期的星期碼
calendar.weekday(year,month,day)
返回給定日期的日期碼。0(星期一)到6(星期日)。月份為 1(一月) 到 12(12月)。
import calendar
print(calendar.weekday(2017,11,17))
#4
9、設(shè)置一周里那一天作為第一天
calendar.setfirstweekday(weekday)
設(shè)置每周的起始日期碼。0(星期一)到6(星期日)。
import calendar
print(calendar.firstweekday())
calendar.setfirstweekday(calendar.SUNDAY)
print(calendar.firstweekday())
#0
#6
10、將tupletime轉(zhuǎn)成時(shí)間戳
calendar.timegm(tupletime)
和time.gmtime相反:接受一個(gè)時(shí)間元組形式,返回該時(shí)刻的時(shí)間輟(1970紀(jì)元后經(jīng)過(guò)的浮點(diǎn)秒數(shù))。
import calendar,time
now = time.localtime()
date = calendar.timegm(now)
print(date)
#1510940959