程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

23.Python文件I/O(一)【詳解open()函數&上下文管理器with...as】

編輯:Python

目錄:

  • 每篇前言:
  • Python文件I/O(一)
    • 1.1 基本方法
      • 1.1.1 打開和關閉文件
      • 1.1.2 file對象的屬性
      • 1.1.3 知識點補給站
      • 1.1.4 文件基本讀寫與定位
      • 1.1.5 close()
      • 1.1.6 file(文件)的方法
      • 1.1.7 上下文管理 with.......as

每篇前言:

  • 作者介紹:【孤寒者】—CSDN全棧領域優質創作者、HDZ核心組成員、華為雲享專家Python全棧領域博主、CSDN原力計劃作者

  • 本文已收錄於Python全棧系列專欄:《Python全棧基礎教程》
  • 熱門專欄推薦:《Django框架從入門到實戰》、《爬蟲從入門到精通系列教程》、《爬蟲高級》、《前端系列教程》、《tornado一條龍+一個完整版項目》。
  • ​本專欄面向廣大程序猿,為的是大家都做到Python從入門到精通,同時穿插有很多很多習題,鞏固學習。
  • 訂閱專欄後可私聊進一千多人Python全棧交流群(手把手教學,問題解答);進群可領取Python全棧教程視頻 + 多得數不過來的計算機書籍:基礎、Web、爬蟲、數據分析、可視化、機器學習、深度學習、人工智能、算法、面試題等。
  • 加入我一起學習進步,一個人可以走的很快,一群人才能走的更遠!

Python文件I/O(一)

1.1 基本方法

1.1.1 打開和關閉文件

用open()函數打開一個文件,創建一個file對象,調用相關的方法即可對文件進行讀寫。
完整的語法格式為:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True)

參數說明:

  • file: 必需,文件路徑(可以是絕對路徑,也可以是相對路徑)。
  • mode: 可選,文件打開模式。
  • buffering: 寄存區的緩沖大小。設為0,不會有寄存。設為負值,寄存區的緩沖大小則為系統默認。默認寄存區的緩沖大小為0。
  • encoding: 一般使用utf8。
  • errors: 報錯級別。
  • newline: 區分換行符。
  • closefd: 傳入的file參數類型。

mode具體參數列表:

總結:

  • 加個b的作用:以二進制的格式打開文件(比如操作音頻文件,圖片文件,視頻文件…),進行上述操作。

1.1.2 file對象的屬性

以下是和file對象相關的所有屬性的列表:

  • file 對象的 close()方法刷新緩沖區裡任何還沒寫入的信息,並關閉該文件,這之後便不能再進行寫入。

  • 當一個文件對象的引用被重新指定給另一個文件時,Python 會關閉之前的文件。用 close()方法關閉文件是一個很好的習慣。

  • 注意:打開一個文件操作完之後,一定要關閉。

1.1.3 知識點補給站

  • windows系統中:
    相對路徑:不帶盤符的。
    絕對路徑:帶盤符的。
  • 光標位置:
    1.如果讀完了就讀不了了,因為光標的位置在最後
    2.通過seek方法重新調整光標的位置
    3.寫完了後,光標位置在最後
    例子看看:

f = open(r’ceshi.py’,‘r+’)
f.read()
‘wumou love zhangmou’
f.read() #現在就讀不了了,因為光標在上一次讀完之後移動到了最後。
‘’
f.seek(0) #把光標位置調整到最前面,那麼光標後面就有內容了
0
f.read() #現在就可以讀到內容了
‘wumou love zhangmou’
f.tell() #可以查看光標的位置
24
f.seek(0)
0
f.tell()
0

上述方法下一小節會細講~

1.1.4 文件基本讀寫與定位

  • write()方法可將任何字符串寫入一個打開的文件。
    語法:fileObject.write(string)

  • read()方法從一個打開的文件中讀取指定長度的字符串(括號裡加要讀的指定的字符串長度,不寫則全讀)。
    語法:fileObject.read([count])

  • tell()描述文件當前位置
    語法:fileObject.tell()

  • seek()改變當前文件的位置
    語法:seek(offset [,from])
    參數:
    offset變量表示要移動的字節數
    from變量指定參考位置。0,表示開頭。1,表示當前的位置。2,表示末尾(默認為0)
    例如:
    seek(x,0) : 從起始位置即文件首行首字符開始移動 x 個字符
    seek(x,1) : 表示從當前位置往後移動x個字符
    seek(-x,2):表示從文件的結尾往前移動x個字符

實戰講解:

# -*- coding: utf-8 -*-
""" __author__ = 小小明-代碼實體 """
# 以二進制格式打開一個文件用於讀寫.如果該文件已存在則將其覆蓋。如果該文件不存在,創建新文件。
fo = open("foo.txt", "wb+")
# 向文件寫入2句話
fo.write(b"blog.xiaoxiaoming.xyz!\nVery good site!\n")
seq = [b"blog.xiaoxiaoming.xyz!\n", b"Very good site!"]
fo.writelines(seq)
# 查找當前位置
print("當前文件位置 : ", fo.tell())
# 寫完數據,文件指針在文件末尾,現在重定向到文件開頭
fo.seek(0)
# 讀取10個字符
print("當前文件位置 : ", fo.tell())
str = fo.read(10)
print("讀取的字符串是 : ", str)
print("當前文件位置 : ", fo.tell())
# 關閉打開的文件
fo.close()

foo.txt文件內容:

1.1.5 close()

處理完一個文件後, 調用 f.close() 來關閉文件並釋放系統的資源,如果嘗試再調用該文件,則會拋出異常。

>>> f.close()
>>> f.read()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: I/O operation on closed file

當處理一個文件對象時, 使用 with 關鍵字是非常好的方式。在結束後, 它會幫你正確的關閉文件。 而且寫起來也比 try - finally 語句塊要簡短:

>>> with open('/tmp/foo.txt', 'r') as f:
... read_data = f.read()
>>> f.closed
True

1.1.6 file(文件)的方法

file 對象使用 open 函數來創建,下表列出了 file 對象常用的函數:

  • 調用read()會一次性讀取文件的全部內容,如果文件有10G,內存就爆了,所以,要保險起見,可以反復調用read(size)方法,每次最多讀取size個字節的內容。
  • 調用next()或readline()可以每次讀取一行內容,f.next() 逐行讀取數據,和f.readline() 相似,唯一不同的是,readline() 讀取到最後如果沒有數據會返回空,而next() 沒讀取到數據則會報錯。
  • 調用readlines()一次讀取所有內容並按行返回list。因此,要根據需要決定怎麼調用。
  • 如果文件很小,read()一次性讀取最方便;如果不能確定文件大小,反復調用read(size)比較保險;如果是配置文件,調用readlines()最方便。

可能有小伙伴不是很理解flush()的作用,其實我們可以淺顯的將它的作用理解為保存。下面來個代碼講解一下:

舉個例子:
文件內容是: wumou
>> f1 = open('ceshi.py','a')
>> f1.write('shuai')
5
>> f2 = open('ceshi.py','r')
>> f2.read() #會發現現在讀是讀不到剛剛以追加方式寫進入的內容shuai
'wumou'
>> f1.flush() #我們立即刷新緩沖,那麼下面就可以讀到了。此處作用相當於在進行文件操作之後進行保存
>> f2.seek(0)
0
>> f2.read()
'wumoushuai'

實戰講解:

  • 創建tmp.txt文件內容為:
  • 上代碼:
# -*- coding: utf-8 -*-
""" __author__ = 小小明-代碼實體 """
fo = open("tmp.txt", "r", encoding="utf-8")
# 立即刷新緩沖區 ——> 可以理解為保存 
fo.flush()
print("文件名為: ", fo.name)
print("文件描述符為: ", fo.fileno())
print("文件連接到一個終端設備:", fo.isatty())
# next返回文件下一行
for index in range(5):
line = fo.readline()
print("第 %d 行 - %s" % (index + 1, line), end="")
print()
fo.seek(0)
for line in fo.readlines():
print(line, end="")
# 關閉文件
fo.close()

總結:

  • 持久存儲:保存內存中數據都是易丟失的,只有保存在硬盤中才能持久的存儲,保存在硬盤中的基本方法就是把數據寫入文件中。
  • 打開和關閉:在python中文件的打開與關閉變得十分簡單快捷,文件在關閉的時候就會自動保存。

1.1.7 上下文管理 with…as

每次都寫try … finally來關閉文件實在太繁瑣,所以,Python引入了with語句來自動幫我們調用close()方法,代碼如下:

with open("tmp.txt", encoding="utf-8") as f:
for line in f:
print(line, end="")
  • 作用:
    讓python自動執行關閉過程,即調用close()方法。
    管理多個文件自動關閉。

首先來看,單個文件操作時:

# -*- coding: utf-8 -*-
""" __author__ = 孤寒者 """
with open(file_path, mode='r') as f:
# 對f進行一系列操作
# 也可以執行別的操作
# 跳出with語句的時候自動執行f.close()

然後來看,多個文件操作時:

# -*- coding: utf-8 -*-
""" __author__ = 孤寒者 """
with open(file_path, mode='r') as f1,\
open(file_path, mode='r') as f2,\
.
.
.
open(file_path, mode='r') as fn:
# 對f進行一系列操作
# 也可以執行別的操作
file.closed 查看文件是否關閉了
# 跳出with語句塊的時候自動執行f.close()

最後來看看:
兩個底層方法:__enter____exit__

# -*- coding: utf-8 -*-
""" __author__ = 孤寒者 """
class Person:
def __enter__(self): # 進入的時候自動調用
print('this is enter')
return '吳某好帥'
def __exit__(self,exc_type,exc_val,exc_tb): #退出的時候自動調用
print("this is exit")
#with可以打開類,進行多個方法的管理
a = Person()
with a as f: #with可以管理多個軟件,打開多個軟件。
print(111) #我們打開這個類,就會自動調用__enter__方法,然後進行打印111的操作
print(f) #f就是__enter__的返回值
#結束之後就會自動調用__exit__方法


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved