Python3 從零單排2_文件讀寫
文件操作其實和我們日常處理文件一樣的,先打開文件,然後操作,最後保存關閉,在python裏就是這三步驟:
1、打開文件獲取文件的句柄,句柄就理解為這個文件
2、通過文件句柄操作文件
3、關閉文件
文件操作有以下三個模式:
r:讀模式【可讀; 不可寫,不存在則報錯】
w:寫模式【不可讀;不存在則創建;存在則刪除內容】 //註意:只要寫了w模式,不論後面跟的啥,文件不存在則創建,存在則清空文件內容,然後再寫。
a:追加模式【不可讀; 不存在則創建;存在則只追加內容】//註意:追加內容是在最後的指針位置開始寫,所以一般這樣的話,要先f.seek(0),回到文件的第一行第一個字節的位置。
在模式後面跟上‘+‘號,則表示同時可以讀寫文件:
r+:【可讀、可寫;可追加,如果打開的文件不存在的話,會報錯】
w+:【寫讀模式,使用w+的話,已經存在的文件內容會被清空,可以讀到已經寫的文件內容】
a+:【追加讀寫模式,不存在則創建;存在則只追加內容;】
在模式後面跟上‘b‘,則表示處理二進制文件:rb,wb,ab
1.讀取文件
f=open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)#mac下不需要設置字符類型,操作系統默認字符類型是utf-8;windows需要設置這個字符類型,系統默認的是gbk字符類型 print(f.read())#讀取文件內容,返回的是一個字符串,當文件太大時,不建議這樣操作,防止內存撐爆print(f.readlines())#讀取文件內容,返回的是一個list,list每個元素是文件的每一行 print(f.readline())#每次只讀取一行 f.close() #for循環文件句柄是通過行循環文件的內容,這樣做的好處是當文件太大時,防止內存撐爆 f=open(‘a.txt‘,‘r‘,encoding=‘utf-8‘) print(f.read()) i=1 for content in f: print(‘第{line}行:{content}‘.format(line=i,content=content)) i+=1 f.close()
2.寫文件
f=open(‘a.txt‘,‘w‘,encoding=‘utf-8‘) f.write(‘hahaha‘)#只能寫字符串,不能是列表 f.writelines([‘aaa‘,‘bbb‘,‘ccc‘])#寫的是list f=open(‘a.txt‘,‘r+‘,encoding=‘utf-8‘)#r+讀寫模式,只要有r權限在,當文件不存在時都會報錯 f.write(‘1111‘)#讀寫模式下,寫數據的時候會從第一行開始寫,替換之前文件裏第一行的內容前n個字符(n為寫入的字符長度) f=open(‘a.txt‘,‘w+‘,encoding=‘utf-8‘) f.write(‘asd‘) f.seek(0)#seek(n),移動指針到n位置,0為首位 print(f.read())
3.追加模式
追加模式跟上面的差不多,要註意的地方是:追加內容是在最後的指針位置開始寫,所以一般這樣的話,要先f.seek(0),回到文件的第一行第一個字節的位置,要時刻關註指針的位置。
f=open(‘a.txt‘,‘a+‘,encoding=‘utf-8‘) f.seek(0) print(f.read()) i=1 for content in f: print(‘第{line}行:{content}‘.format(line=i,content=content)) i+=1 f.close()
4.with方法操作文件
with方法操作文件,可以少些close文件關閉方法,這個with會自動關閉文件,不需要我們自己再重復寫了,其他用法一樣。
with open(‘a.txt‘,‘r‘) as f: for line in f: print(line)
5.文件修改
有一個細節,日常修改文件的時候,打開文件的時候,會產生一個隱藏文件,其實我們修改的內容過程是這樣的:打開文件->在隱藏的那個文件上增刪改文件內容->保存隱藏文件->之前的文件刪除->隱藏文件重命名開始的文件名稱,是這樣一個過程,那麽我們要修改文件時,其實是一樣的:
1.讀模式打開待修改的文件A
2.修改讀取到的內容
3.將修改後的內容寫進新的文件B
4.刪除文件A
5.將文件B重命名為A
import os with open(‘陽光總在風雨後.txt‘,‘r‘,encoding=‘utf-8‘) as f1,open(‘a.txt‘,‘w‘,encoding=‘utf-8‘) as f2: for line in f1: new_line=line.replace(‘陽光‘,‘彩虹‘) f2.write(new_line) os.remove(‘陽光總在風雨後.txt‘) os.rename(‘a.txt‘,‘陽光總在風雨後.txt‘)
當然還有另外一種方法,不需要刪文件,直接清空文件即可
f1=open(‘陽光總在風雨後.txt‘,‘a+‘,encoding=‘utf-8‘) f1.seek(0) res=f1.read() new_content=res.replace(‘彩虹‘,‘陽光‘) f1.seek(0) f1.truncate() f1.write(new_content) f1.close()
6.集合
集合也是數據類型,,一個類似列表東西,它的特點是無序的,不重復的,也就是說集合中是沒有重復的數據,作用如下:
1、它可以把一個列表中重復的數據去掉,而不需要你再寫判斷
2、可以做關系比較,比如數學裏的交集、並集等
集合的操作和列表差不多:
lis=[1,2,3,4,4,5,5,6,7,8,9] myset=set(lis) #這就定義了一個集合 print(myset) #去掉了重復數據,4,5,這裏只顯示一次 myset.add(888)#添加元素 myset.update([777,666,666]) #添加值 myset.remove(777)#刪除元素,如果元素不存在會報錯 myset.pop()#刪除一個隨機的元素,並返回刪除的元素 myset.discard(‘dddd‘)#如果刪除的元素存在,刪除,不存在不做處理
集合操作方法:
set1 = {1, 2, 3, 4, 5, 6, 7,8,9} set2 = {1, 2, 3, 4, 6} set3 = {1, 2} print(set1.intersection(set2)) # 取交集,也就是取set1和set2中都有的 print(set1 & set2)# 取交集 print(set1.union(set2)) # 取並集,也就是把set1和set2合並了,然後去除重復的 print(set1 | set2)# 取並集 print(set1.difference(set2)) #取差集 在list中存在,在set2中沒有的 print(set1 - set2) print(set3.issubset(set1))#判斷set3是不是set1的子集 print(set1.issuperset(set3))#判斷set1是不是set3的父集 print(set1.isdisjoint(set3))#判斷set1和set3是否有交集 print(set1.symmetric_difference(set2))#對稱差集,輸出兩個列表中都沒有的值,也就是把兩個集合中相同的去掉 print(set1 ^ set2)
7.寫一個監控服務器的腳本,每分鐘運行一次,這分鐘內如果ip訪問次數超過200,則計入黑名單。
log日誌文件格式如下:
58.19.57.99 - - [04/Jun/2017:05:23:30 +0800] "GET / HTTP/1.0" 302 161 "-" "Wget/1.12 (linux-gnu)" "-"
58.19.57.99 - - [04/Jun/2017:05:23:30 +0800] "GET /blog HTTP/1.0" 301 233 "-" "Wget/1.12 (linux-gnu)" "-"
import time pin=0 while True: with open(‘access.log‘,‘rb‘) as f: ip_list=[] f.seek(pin) for line in f: ip=line.decode().split()[0] print(ip) ip_list.append(ip) for ip in set(ip_list): if ip_list.count(ip)>=200: print(‘黑名單:%s,訪問次數:%d‘%(ip,ip_list.count(ip))) pin=f.tell() print(pin) time.sleep(5)
Python3 從零單排2_文件讀寫