1. 程式人生 > >Python3 從零單排2_文件讀寫

Python3 從零單排2_文件讀寫

數據 ace repl see 彩虹 定義 txt 沒有 寫文件

  文件操作其實和我們日常處理文件一樣的,先打開文件,然後操作,最後保存關閉,在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_文件讀寫