前言
嗨嘍,大家好呀~這里是愛看美女的茜茜吶
又到了學Python時刻~
今天咱們來了解一下 fileinput 。
說到fileinput,可能90%的碼農表示沒用過,甚至沒有聽說過。
這不奇怪,因為在python界,既然open可以走天下,何必要fileinput呢?
但是,今天我還是要介紹fileinput這個方法,因為太奈斯了。
不止是香。是真香!
接下來,就跟著我,一起fileinput,對,就是這個feel。
正文
1、方法介紹
基本用法
先來看一下fileinput
的基本功能:
-
fileinput.filename()
:返回當前被讀取的文件名。
—>在第一行被讀取之前,返回 None
。
-
fileinput.fileno()
:返回以整數表示的當前文件“文件描述符”。
—>當未打開文件時(處在第一行和文件之間),返回 -1
。
-
fileinput.lineno()
:返回已被讀取的累計行號。
—>在第一行被讀取之前,返回 0
。在最后一個文件的最后一行被讀取之后,返回該行的行號。
-
fileinput.filelineno()
:返回當前文件中的行號。
—>在第一行被讀取之前,返回 0
。
—>在最后一個文件的最后一行被讀取之后,返回此文件中該行的行號。
進階用法
fileinput.isfirstline()
:如果剛讀取的行是其所在文件的第一行則返回 True,否則返回 False。fileinput.isstdin()
:如果最后讀取的行來自 sys.stdin 則返回 True,否則返回 False。fileinput.nextfile()
:關閉當前文件以使下次迭代將從下一個文件(如果存在)讀取第一行;不是從該文件讀取的行將不會被計入累計行數。直到下一個文件的第一行被讀取之后文件名才會改變。
—>在第一行被讀取之前,此函數將不會生效;它不能被用來跳過第一個文件。
—>在最后一個文件的最后一行被讀取之后,此函數將不再生效。
-
fileinput.close()
:關閉序列。
2、 默認讀取
代碼示例
import fileinput
'當 Python 腳本沒有傳入任何參數時,fileinput 默認會以 stdin 作為輸入源'
for line in fileinput.input():
print(f'{line}')
運行結果
你輸入的內容,程序都會讀取并再輸出。
俗稱:復讀機
3、處理一個文件
代碼示例
import fileinput
'files 輸入打開文件的名稱即可'
with fileinput.input(files=('output.txt',)) as file:
for line in file:
print(f'{fileinput.filename()} 第{fileinput.lineno()}行:{line}',end='')
運行結果
解析:
fileinput
有且僅有這兩種讀取模式:‘r’,‘rb’
;fileinput.input()
默認使用 mode=‘r’ 的模式讀取文件,如果你的文件是二進制的,可以使用mode=‘rb’
模式。
4、處理批量文件
多文件序號連續排序
調用方法
-
fileinput.lineno()
方法
代碼示例
import fileinput
'files 輸入打開文件的名稱即可'
with fileinput.input(files=('output.txt','input.txt')) as file:
for line in file:
#fileinput.lineno() 把兩個文件的整合陳一個文件對象file,需要排序輸出
print(f'{fileinput.filename()} 第{fileinput.lineno()}行: {line}', end='')
# fileinput.filelineno()兩個文件單獨讀取,需要單獨排序
print(f'{fileinput.filename()} 第{fileinput.filelineno()}行: {line}', end='')
運行結果
多文件序號單獨排序
調用方法
-
fileinput.filelineno()
方法
代碼示例
import fileinput
'files 輸入打開文件的名稱即可'
with fileinput.input(files=('test1.txt','test2.txt')) as file:
for line in file:
# fileinput.filelineno()兩個文件單獨讀取,需要單獨排序
print(f'{fileinput.filename()} 第{fileinput.filelineno()}行: {line}', end='')
運行結果
與glob配合用法
在顏值的時代,上面的輸出樣式,已經無法滿足我們的需要了,于是乎,我們就想到了glob
。
代碼示例
import fileinput
import glob
#glob 匹配te開頭的txt文件
for line in fileinput.input(glob.glob("te*.txt")):
if fileinput.isfirstline():
#輸出讀取文件
print('='*10,f'讀取文件{fileinput.filename()}','='*10)
#fileinput.filelineno()方法讀取
print(str(fileinput.filelineno())+ ':'+line.upper(),end='')
運行結果
就這顏值,哪個小姐姐能不喜歡呢。
5、讀取與備份
調用方法
-
fileinput.input 的backup
參數,可以指定備份的后綴名,比如.bak
代碼示例
import fileinput
#觸發backup的動作,源文件內容被修改,對源文件進行backup
with fileinput.input(files=("test1.txt",), backup=".bak",inplace=1) as file:
for line in file:
print(line.rstrip().replace('111111', '222222'))
print(f'{fileinput.filename()} 第{fileinput.lineno()}行: {line}', end='')
運行結果
6、重定向替換
解析
上面的例子, 用到了 inplace
參數,表示是否將標準輸出的結果寫回文件,默認不取代。
代碼示例:
import fileinput
#觸發backup的動作,源文件內容被修改,對源文件進行backup
with fileinput.input(files=("test2.txt",), inplace=True) as file:
print("[INFO] task is started...")
for line in file:
print(f'{fileinput.filename()} 第{fileinput.lineno()}行: {line}', end='')
print("[INFO] task is closed...")
運行結果
注
通過運行結果,可以看到:
在
for
循環體內的print
內容會寫回到原文件中了。而在
for
循環體外的print
則沒有變化。
7、進階
openhook
含義解析
在 fileinput.input() 中有一個 openhook 的參數,它支持用戶傳入自定義的對象讀取方法;
如果沒有傳入任何勾子,fileinput 默認使用的是 open 函數;
方法介紹
fileinput
內置了兩種勾子
1、fileinput.hook_compressed(filename, mode)
使用
gzip
和bz2
模塊透明地打開gzip
和bzip2
壓縮的文件(通過擴展名‘.gz’
和‘.bz2’
來識別);如果文件擴展名不是
‘.gz’
或‘.bz2’
,文件會以正常方式打開(即使用open()
并且不帶任何解壓操作);
使用示例: fi = fileinput.FileInput(openhook=fileinput.hook_compressed)
2、fileinput.hook_encoded(encoding, errors=None)
- 返回一個通過
open()
打開每個文件的鉤子,使用給定的encoding
和errors
來讀取文件。
使用示例: fi = fileinput.FileInput(openhook=fileinput.hook_encoded(“utf-8”, “surrogateescape”))
示例實戰
假如我想要使用 fileinput
來讀取網絡上的文件,思路:
先使用
requests
下載文件到本地再使用
open
去讀取它;
def online_open(url, mode):
import requests
r = requests.get(url)
filename = url.split("/")[-1]
with open(filename,'w') as f1:
f1.write(r.content.decode("utf-8"))
f2 = open(filename,'r')
return f2
直接將這個函數傳給 openhook
即可:
# -*- coding:utf-8 -*-
# @Time : 2022-07-23
# @Author : carl_DJ
import fileinput
file_url = 'https://www.csdn.net/robots.txt'
with fileinput.input(files=(file_url,), openhook=online_open) as file:
for line in file:
print(line, end="")
代碼整合:
# -*- coding:utf-8 -*-
# @Time : 2022-07-23
# @Author : carl_DJ
def online_open(url, mode):
import requests
r = requests.get(url)
filename = url.split("/")[-1]
with open(filename,'w') as f1:
f1.write(r.content.decode("utf-8"))
f2 = open(filename,'r')
return f2
import fileinput
file_url = 'https://www.csdn.net/robots.txt'
with fileinput.input(files=(file_url,), openhook=online_open) as file:
for line in file:
print(line, end="")
小伙伴們在學習Python的過程中,有時候不知道怎么學,從哪里開始學。掌握了一些基本的知識或者做了一些案例后,不知道下一步怎么走,不知道如何去學習更加高深的知識。
那么對于這些大兄弟們,我準備了大量的免費視頻教程,PDF電子書籍,以及源代碼!
==點擊 藍色字體 自取,我都放在這里了。==
還會有大佬解答!
運行結果
總結
關于fileinput的介紹,也就介紹到這里。
fileinput本身是對 open 函數的再次封裝,所以在讀取的cc部分,就比open顯得更專業,更優雅,這也是僅限于讀取的方面。
在寫的方面,相對于open,就不是那么的強悍。
歸根結底,fileinput還是一個不錯的方法。值得你擁有。
希望本篇文章有對你帶來幫助 ??,有學習到一點知識~