轉載https://blog.csdn.net/weixin_44015805/article/details/99884093
Py文件操作庫及應用(os、sys、pathlib ; open、fileinput、linecache)
# -*- coding: utf-8 -*-
'''
Py文件操作庫及應用.py
(os、sys、pathlib ; open、fileinput、linecache)
深入:
注意:
一、文件編碼解碼問題
open(file,mode='a+', encoding='utf-8')
注意打開模式mode爲帶b的二進制打開模式時的後期輸出時的解碼才能輸出中文問題,且編碼解碼注意一致。
使用:
一、文件系統級操作
1、os
2、sys
3、pathlib 提供了一組面向對象的類,類可代表各種操作系統上的路徑
Path類 是 PurePath 的子類,除了支持 PurePath 的各種操作、屬性和方法之外,
Path類會真正訪問底層的文件路徑,提供了屬性和方法來訪問底層的文件系統。
二、文件應用級操作
1、open
2、fileinput 迭代一系列文本文件中的所有行。其中input函數,可以把多個輸入流合併在一起,然後進行一些循環操作等
fileinput.input()支持從命令行輸入參數 即文件名(多個文件名用 files=[,])
3、linecache 從文件中(所有utf-8文件中)讀取指定行(所有行),並在內部使用緩存優化存儲。
'''
# =============================================================================
# #文件系統級操作
# #(os、sys、pathlib)
# =============================================================================
# =============================================================================
# #os模塊
# #os模塊訪問多個操作系統服務
# #os及其子模塊os.path包含多個查看、創建和刪除目錄及文件的函數,以及一些操作路徑的函數。如os.path.split 和 os.path.join
# =============================================================================
####################
#探索os模塊
import os
help(os) #獲取幫助信息
os.__doc__ #獲取文檔信息
os.__file__ #獲取源碼文件路徑
os.__all__ #獲取導入所有名稱列表
os.__name__
dir(os) #打印所有 屬性、方法、類。
help(os.environ) #包含環境變量的映射 如訪問環境變量PATHONPATH,則使用 os.environ['PYTHONPATH]
help(os.system) #系統命令 在子shell中執行命令
help(os.sep) #路徑中使用的分隔符
####################
#常用的變量、函數、類
#訪問環境變量 PYTHONPATH
os.environ['PYTHONPATH'] #訪問環境變量 PYTHONPATH
#運行命令行命令 直接輸入CMD命令
os.system('cmd') #運行命令行命令 直接輸入CMD命令
os.system('shutdown -s -t 300') #自動關機 300秒後
#打開一個路徑/程序
os.startfile('C:\\Users\\Administrator\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe')
print(os.name) # 顯示導入依賴模塊的操作系統的名稱
os.getenv('PYTHONPATH') # 獲取PYTHONPATH環境變量的值
os.getlogin() # 返回當前系統的登錄用戶名
os.getpid() # 獲取當前進程ID
os.getppid() # 獲取當前進程的父進程ID
os.cpu_count() # 返回當前系統的CPU數量
os.sep # 返回路徑分隔符
os.pathsep # 返回當前系統的路徑分隔符
os.linesep # 返回當前系統的換行符
os.urandom(3) # 返回適合作爲加密使用的、最多3個字節組成的bytes
####################
#與目錄相關的函數
#獲取當前目錄
os.getcwd() #獲取當前目錄
#改變當前目錄到指定目錄
os.chdir('F:/SpyderXIANGMUWENJIANJIA/編程基礎') #改變當前目錄到指定目錄
os.getcwd() #再次獲取當前目錄
#返回指定目錄下的所有文件和子目錄
os.listdir(os.getcwd()) #返回指定目錄下的所有文件和子目錄
#創建、重命名、刪除等操作
#os.mkdir('os.mkdir測試創建目錄',777) #當前目錄下創建子目錄 如果中間目錄爲空則報錯
#os.rename('os.mkdir測試創建目錄','o') #重命名當前目錄下的子目錄
#os.makedirs('os.mkdir測試創建目錄1\\遞歸目錄1\\遞歸目錄2',777) #遞歸創建/a/b/c連環目錄,比mkdir強大
#os.renames('os.mkdir測試創建目錄1\\遞歸目錄1\\遞歸目錄2','a\\b\\c') #遞歸重命名連環目錄
#os.remove('b.txt') # 刪除文件 b.txt
#os.rmdir('o') #刪除當前目錄下的子目錄 目錄需要爲空,否則報錯。
#os.removedirs('a\\b\\c') #遞歸刪除連環目錄 如果沒有找到目錄則報錯
####################
#os.path模塊
#os.path模塊提供了操作目錄的方法。
import os,time
print(os.path.abspath('abc.txt')) #獲取絕對路徑
print(os.path.abspath('.')) #獲取當前路徑的絕對路徑
print(os.path.commonprefix(['/usr/lib','/usr/local/lib'])) #獲取共同前綴
print(os.path.commonpath(['usr/lib','usr/local/lib'])) #獲取共同路徑
print(os.path.dirname('abc/xyz/README.txt')) #獲取目錄
print(os.path.exists('abc/xyz/README.txt')) #判斷指定目錄是否存在
print(time.ctime(os.path.getatime('Py文件庫linecache.py'))) #獲取最近一次訪問時間
print(time.ctime(os.path.getmtime('Py文件庫linecache.py'))) #獲取最後一次修改時間
print(time.ctime(os.path.getctime('Py文件庫linecache.py'))) #獲取創建時間
print(os.path.getsize('Py文件庫linecache.py')) #獲取文件大小
print(os.path.isfile('Py文件庫linecache.py')) #判斷是否爲文件 # True
print(os.path.isdir('Py文件庫linecache.py')) #判斷是否爲目錄 # False
print(os.path.samefile('Py文件庫linecache.py', './Py文件庫linecache.py')) #判斷是否爲同一個文件 # True
# =============================================================================
# #sys模塊
# #sys模塊訪問與python解釋器緊密相關的變量和函數
# =============================================================================
####################
#探索sys模塊
import sys,pprint #打印函數,能夠妥善的打印輸出
help(sys) #獲取幫助信息
sys.__doc__ #獲取文檔信息
dir(sys) #打印包內所有 變量、函數、類等
help(sys.path) #python的搜索路徑的目錄列表,是一個字符串列表,其中每個字符串都是一個目錄名
help(sys.modules) #將模塊名映射到模塊(僅限當前導入的模塊)
help(sys.exit) #退出當前程序。可提供一個整數參數,支出程序是否成功
#應用於 try/finally 異常捕獲時子句依然會執行。
help(sys.argv) #獲取命令行輸入參數 sys.argv[]
#包含傳傳遞給python解釋器的參數,包括腳本名,
#可應用於命令行
####################
#常用變量、函數、類
##########
#模塊搜索路徑列表中的 sit-packages目錄 就是專門用來安放模塊的目錄。
print(sys.path) #輸出python的搜索路徑的目錄列表
pprint.pprint(sys.path) #格式化打印函數
##########
#程序退出 sys.exit()
'''
sys.exit()會引發一個異常:SystemExit,如果這個異常沒有被捕獲,那麼python解釋器將會退出。
如果有捕獲此異常的代碼,那麼這些代碼還是會執行。捕獲這個異常可以做一些額外的清理工作。
0爲正常退出,其他數值(1-127)爲不正常,可拋異常事件供捕獲。也可添加異常提示信息。
os._exit()會直接將python程序終止,之後的所有代碼都不會繼續執行。
'''
help(sys.exit)
sys.exit.__doc__
#sys.exit('hahaha') #退出程序,並拋出異常。
try:
sys.exit()
except SystemExit: #捕獲異常,做一些額外的清理工作。
print('die')
finally:
print('這裏通過sys.exit()方法已程序退出,餘下代碼不再執行。')
#import os
#os._exit(0)
####################
#示例1
#sys.argv示例 獲取命令行輸入參數 sys.argv[]
#從命令行輸入命令, 通過提供命令行輸入的參數來執行源碼內容
#命令行輸入格式: python py文件名 參數1 參數2
#sys.argv[] 是用來獲取命令行輸入的參數的(參數和參數之間空格區分),
#sys.argv[0] 參數表示代碼本身文件路徑,所以從參數1開始,表示獲取的參數了
'''
參考網址:
https://blog.csdn.net/u013205877/article/details/78571453
'''
#testSys_命令行參數.py
#自建測試文件 testSys_命令行參數.py 輸出命令行參數
import sys
print('執行程序,參數爲{}'.format(sys.argv[1:]))
#testSys_反轉命令行參數.py
#自建測試文件 testSys_命令行參數.py 輸出反向排序的命令行參數
import sys
args=sys.argv[1:]
args.reverse()
print('反轉參數輸出: ',' '.join(args))
####################
#示例2
#sys.path應用示例 sys.path.append() 動態修改添加python模塊加載路徑
#scrapy框架爬蟲出現No module named: 的問題
'''
python執行的時候,是根據最初設置的python路徑,
而我們創建的scrapy的路徑不在上面路徑的情況下,導致scrapy找不到路徑,所以把該路徑添加到python執行路徑即可;
添加搜索路徑至python搜索包路徑的目錄列表裏就好,如下,然後重啓程序運行即可。
'''
import os,sys
ffpath = os.path.dirname(os.path.dirname(os.path.abspath("."))) #獲取目錄名稱os.path.dirname(),獲取絕對路徑os.path.abspath('.')
sys.path.append(ffpath)
# =============================================================================
# #pathlib模塊
# #pathlib模塊提供了一組面向對象的類,這種類可代表各種操作系統上的路徑
# =============================================================================
'''
繼續深入:
參考文檔
https://docs.python.org/3/library/pathlib.html
'''
import pathlib
from pathlib import *
####################
#探索模塊
help(pathlib)
pathlib.__doc__
pathlib.__file__
pathlib.__all__
dir(pathlib)
help(pathlib.PurePath) #PurePath類有兩個子類,即 PurePosixPath 和 PureWindowsPath,分別代表 UNIX 風格的路徑(包括 Mac OS X)和 Windows 風格的路徑。;
help(pathlib.Path) #Path類有兩個子類, 即 PosixPath 和 WindowsPath
####################
#常用屬性、函數、類
'''
pathlib模塊提供的一組面向對象的類,這種類可代表各種操作系統上的路徑。
PurePath類 PurePath類有兩個子類,即 PurePosixPath 和 PureWindowsPath,分別代表 UNIX 風格的路徑(包括 Mac OS X)和 Windows 風格的路徑。;
PurePath只是代表特定平臺的路徑字符串(它們本質上就是字符串)
Path類 Path類有兩個子類,即 PosixPath 和 WindowsPath
Path 是 PurePath 的子類,除了支持 PurePath 的各種操作、屬性和方法之外,
還會真正訪問底層的文件系統,包括判斷 Path 對應的路徑是否存在,獲取 Path 對應路徑的各種屬性(如是否只讀、是文件還是文件夾等),甚至可以對文件進行讀寫。
PurePath 和 Path 最根本的區別在於,PurePath 處理的僅是字符串,而 Path 則會真正訪問底層的文件路徑,因此它提供了屬性和方法來訪問底層的文件系統。
'''
help(PurePath) #PurePath類有兩個子類如下:
help(PurePosixPath)
help(PureWindowsPath)
help(Path) #Path類有兩個子類如下:
help(PosixPath)
help(WindowsPath)
#########
#PurePath類
#PurePath只是代表特定平臺的路徑字符串(它們本質上就是字符串)
#創建PurePath類,在windows系統中實際上使用PureWindowsPath類。
help(PurePath)
pp=PurePath('test.py')
print(type(pp)) #如果在 Windows 系統上使用 PurePath 創建對象,程序實際返回 PureWindowsPath 對象。
#PurePath自動組成路徑字符
pp=PurePath('crazyit','some/path','info') #自動組成路徑字符串 #程序在創建 PurePath 和 Path時,既可傳入單個路徑字符串,也可傳入多個路徑字符串,PurePath 會將它們拼接成一個字符串
pp=PurePath() #無參數則默認創建當前路徑,即點號 .
pp=PurePath(Path('crazyit'),Path('info')) #等同於上面的創建路徑方法
pp=PurePosixPath('crazyit', 'some/path', 'info') #明確創建 unix風格 的路徑
#根目錄路徑,只有最後一個生效
pp=PureWindowsPath('c:/windows','d:info') #如果傳入多個根路徑,則只有最後一個根路徑及後面的子路精生效。
pp=PureWindowsPath('c:/windows','/program files') #在windows中只有盤符纔算根路徑
#路徑字符串中多出來的斜槓和點號(代表當前路徑)都會被忽略
#不會忽略兩點..,因爲兩點在路徑中有實際意義(兩點代表上一級路徑)
pp=PurePath('crazyit//info') #輸出 crazyit//info
pp=PurePath('crazyit/./info') #點被忽略,因爲代表當前路徑。等同於上
pp=PurePath('crazyit/../info') #兩個點不被忽略,因爲代表上級目錄
print(pp)
#PurePath類對象的比較運算
#不同風格的 PurePath,unix 和 windows它們依然可以比較是否相等(結果總是返回 False),但不能比較大小,否則會引發錯誤
PurePosixPath('info') == PurePosixPath('INFO') #unix系統的路徑區分大小寫
PureWindowsPath('info') == PureWindowsPath('INFO') #windows系統的路徑不區分大小寫
PureWindowsPath('info') in {PureWindowsPath('INFO')} #注意後面是 set類型集合
PurePosixPath('D:') < PurePosixPath('c:') #unix系統的路徑區分大小寫,所以返回True
PureWindowsPath('D:') > PureWindowsPath('c:') #windows系統的路徑不區分大小寫 所以返回True
#斜槓(/)拼接路徑
#將多個路徑連接起來。不管是 UNIX 風格的路徑,還是 Windows 風格的路徑,都是使用斜槓作爲連接運算符
pp=PureWindowsPath('windows:','abc')
print(pp/'xyz') #拼接多個路徑 windows風格
pp2=PurePosixPath('unix:','hehe') #拼接多個路徑 unix風格
print(pp2/'haha')
print(pp/pp2) #拼接兩個路徑
#PurePath 的本質其實就是字符串,因此程序可使用 str() 將它們恢復成字符串對象
print(str(pp))
#PurePath類屬性和類方法
'''
類屬性和方法名 功能描述
PurePath.parts 該屬性返回路徑字符串中所包含的各部分。
PurePath.drive 該屬性返回路徑字符串中的驅動器盤符。
PurePath.root 該屬性返回路徑字符串中的根路徑。
PurePath.anchor 該屬性返回路徑字符串中的盤符和根路徑。
PurePath.parents 該屬性返回當前路徑的全部父路徑。
PurePath.parent 該屬性返回當前路徑的上一級路徑,相當於 parents[0] 的返回值。
PurePath.name 該屬性返回當前路徑中的文件名。
PurePath.suffixes 該屬性返回當前路徑中的文件所有後綴名。
PurePath.suffix 該屬性返回當前路徑中的文件後綴名。相當於 suffixes 屬性返回的列表的最後一個元素。
PurePath.stem 該屬性返回當前路徑中的主文件名。
PurePath.as_posix() 將當前路徑轉換成 UNIX 風格的路徑。
PurePath.as_uri() 將當前路徑轉換成 URI。只有絕對路徑才能轉換,否則將會引發 ValueError。
PurePath.is_absolute() 判斷當前路徑是否爲絕對路徑。
PurePath.joinpath(*other) 將多個路徑連接在一起,作用類似於前面介紹的斜槓運算符。
PurePath.match(pattern) 判斷當前路徑是否匹配指定通配符。
PurePath.relative_to(*other) 獲取當前路徑中去除基準路徑之後的結果。
PurePath.with_name(name) 將當前路徑中的文件名替換成新文件名。如果當前路徑中沒有文件名,則會引發 ValueError。
PurePath.with_suffix(suffix) 將當前路徑中的文件後綴名替換成新的後綴名。如果當前路徑中沒有後綴名,則會添加新的後綴名。
'''
# 訪問drive屬性
#返回驅動器盤符
print(PureWindowsPath('c:/Program Files/').drive) #返回驅動器盤符 c:
print(PureWindowsPath('/Program Files/').drive) #返回驅動器盤符 ''
print(PurePosixPath('/etc').drive) #返回驅動器盤符 ''
# 訪問root屬性
#返回路徑字符串中的根路徑
print(PureWindowsPath('c:/Program Files/').root) #返回路徑字符串中的根路徑 \
print(PureWindowsPath('c:Program Files/').root) # ''
print(PurePosixPath('/etc').root) # /
# 訪問anchor屬性
#返回路徑字符串中的 盤符和根路徑
print(PureWindowsPath('c:/Program Files/').anchor) # c:\
print(PureWindowsPath('c:Program Files/').anchor) # c:
print(PurePosixPath('/etc').anchor) # /
# 訪問parents屬性
#返回當前路徑的全部福路徑
pp = PurePath('abc/xyz/wawa/haha')
print(pp.parents)
print(pp.parents[0]) # abc\xyz\wawa
print(pp.parents[1]) # abc\xyz
print(pp.parents[2]) # abc
print(pp.parents[3]) # .
# 訪問parent屬性
#返回當前路徑的上一級路徑,相當於parents[0]
print(pp.parent) # abc\xyz\wawa
# 訪問name屬性
#返回當前路徑的路徑名
print(pp.name) # haha
pp = PurePath('abc/wawa/bb.txt')
print(pp.name) # bb.txt
#返回文件的所有後綴名
pp = PurePath('abc/wawa/bb.txt.tar.zip')
# 訪問suffixes屬性
print(pp.suffixes[0]) # .txt
print(pp.suffixes[1]) # .tar
print(pp.suffixes[2]) # .zip
#返回文件的最後一個後綴名
# 訪問suffix屬性
print(pp.suffix) # .zip
#返回路徑中的主文件名
print(pp.stem) # bb.txt.tar
#轉成Unix風格的路徑
print(pp.as_posix()) # abc/xyz/wawa/haha
#將絕對路徑轉換成uri,只有絕對路徑才能轉換
#將相對路徑轉換成Uri引發異常
#print(pp.as_uri()) # ValueError
#創建絕對路徑
pp = PurePath('d:/', 'Python', 'Python3.6')
#將絕對路徑轉換成Uri
print(pp.as_uri()) # file:///d:/Python/Python3.6
#判斷當前路徑是否匹配指定模式
print(PurePath('a/b.py').match('*.py')) # True
print(PurePath('/a/b/c.py').match('b/*.py')) # True
print(PurePath('/a/b/c.py').match('a/*.py')) # False
#創建unix風格絕對路徑
pp = PurePosixPath('c:/abc/xyz/wawa')
#測試relative_to方法
#獲取當前路徑中 去除指定基準路徑 之後的結果
print(pp.relative_to('c:/')) # abc\xyz\wawa
print(pp.relative_to('c:/abc')) # xyz\wawa
print(pp.relative_to('c:/abc/xyz')) # wawa
# 測試with_name方法
#將當前路徑中的主文件名 替換成 指定文件名,若無主文件名則報錯。
p = PureWindowsPath('e:/Downloads/pathlib.tar.gz')
print(p.with_name('fkit.py')) # e:\Downloads\fkit.py
p = PureWindowsPath('c:/')
#print(p.with_name('fkit.py')) # ValueError
# 測試with_suffix方法
#將當前路徑中的 文件後綴名 替換成 指定後綴名,若無則添加後綴名
p = PureWindowsPath('e:/Downloads/pathlib.tar.gz')
print(p.with_suffix('.zip')) # e:\Downloads\pathlib.tar.zip
p = PureWindowsPath('README')
print(p.with_suffix('.txt')) # README.txt
##########
#Path類
#Path 是 PurePath 的子類,除了支持 PurePath 的各種操作、屬性和方法之外,
#還會真正訪問底層的文件系統,包括判斷 Path 對應的路徑是否存在,獲取 Path 對應路徑的各種屬性(如是否只讀、是文件還是文件夾等),甚至可以對文件進行讀寫。
#PurePath 和 Path 最根本的區別在於,PurePath 處理的僅是字符串,而 Path 則會真正訪問底層的文件路徑,因此它提供了屬性和方法來訪問底層的文件系統。
'''
繼續深入,參考文檔:
https://docs.python.org/3/library/pathlib.html
''''
#獲取當前目錄
p=Path('.')
#遍歷當前目錄下所有的 文件和子目錄
for x in p.iterdir():
print(x)
list(p.iterdir())
#獲取上一級目錄
p=Path('../')
#獲取上級目錄 及其 所有子目錄下的py文件
for x in p.glob('**/*.py'):
print(x)
#獲取指定對應目錄
p=Path('F:/SpyderXIANGMUWENJIANJIA')
#獲取 上級目錄 及 所有子目錄下的 指定PY文件
for x in p.glob('**/實盤交易.py'):
print(x)
help(Path)
#創建相對路徑字符串
p = Path('測試文件/testPathlib_A.txt')
#以GBK字符集輸出文本內容
#並實際創建路徑
result = p.write_text('''有一個美麗的新世界
它在遠方等我
那裏有天真的孩子
還有姑娘的酒窩''', encoding='GBK')
#返回輸出的字符數
print(result)
#指定以GBK字符集讀取文本內容
content = p.read_text(encoding='GBK')
#輸出讀取的文本內容
print(content)
#讀取字節內容
bb = p.read_bytes()
print(bb)
# =============================================================================
# #文件應用級操作
# #(open、fileinput、linecache、pathlib)
# =============================================================================
# =============================================================================
# #open
# #open函數位於自動導入的模塊io中
# =============================================================================
'''
深入:
1、標準輸入輸出等(sys.stdin/sys.stdout/sys.stderr)
可應用管道重定向輸出
注意:
1、文件打開模式,直接決定了後續可以對文件做哪些操作。例如,使用 r 模式打開的文件,後續編寫的代碼只能讀取文件,而無法改動文件內容。
2、read()讀取方法的參數如果省略,則默認一次性讀取所有內容。若參數爲數字,則根據打開模式來區分讀取指定字符/字節。
3、讀取後的文件 可當做 迭代器 來使用,可循環,可操作,可list、序列解包、多重賦值等
使用:
1、打開文件 open()
2、讀取操作 read()、readline()、readlines()
3、寫入操作 write()、writelines()
4、關閉文件 close()
5、文件指針 tell()、seek()
'''
####################
#打開文件
'''
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
參數file: 要創建或打開文件的文件名稱,該名稱要用引號(單引號或雙引號都可以)括起來。需要注意的是,如果要打開的文件和當前執行的代碼文件位於同一目錄,則直接寫文件名即可;否則,此參數需要指定打開文件所在的完整路徑。
參數mode: 可選參數,用於指定文件的打開模式。可選的打開模式如表 1 所示。如果不寫,則默認以只讀(r)模式打開文件。
參數buffing: 可選參數,用於指定對文件做讀寫操作時,是否使用緩衝區。
'''
help(open)
open.__doc__
dir(open)
#文件打開模式,直接決定了後續可以對文件做哪些操作。例如,使用 r 模式打開的文件,後續編寫的代碼只能讀取文件,而無法改動文件內容。
'''
open 函數支持的文件打開模式
模式 意義 注意事項
r 只讀模式打開文件,讀文件內容的指針會放在文件的開頭。 操作的文件必須存在。
rb 以二進制格式、採用只讀模式打開文件,讀文件內容的指針位於文件的開頭,一般用於非文本文件,如圖片文件、音頻文件等。
r+ 打開文件後,既可以從頭讀取文件內容,也可以從開頭向文件中寫入新的內容,寫入的新內容會覆蓋文件中等長度的原有內容。
rb+ 以二進制格式、採用讀寫模式打開文件,讀寫文件的指針會放在文件的開頭,通常針對非文本文件(如音頻文件)。
w 以只寫模式打開文件,若該文件存在,打開時會清空文件中原有的內容。 若文件存在,會清空其原有內容(覆蓋文件);反之,則創建新文件。
wb 以二進制格式、只寫模式打開文件,一般用於非文本文件(如音頻文件)
w+ 打開文件後,會對原有內容進行清空,並對該文件有讀寫權限。
wb+ 以二進制格式、讀寫模式打開文件,一般用於非文本文件
a 以追加模式打開一個文件,對文件只有寫入權限,如果文件已經存在,文件指針將放在文件的末尾(即新寫入內容會位於已有內容之後);反之,則會創建新文件。
ab 以二進制格式打開文件,並採用追加模式,對文件只有寫權限。如果該文件已存在,文件指針位於文件末尾(新寫入文件會位於已有內容之後);反之,則創建新文件。
a+ 以讀寫模式打開文件;如果文件存在,文件指針放在文件的末尾(新寫入文件會位於已有內容之後);反之,則創建新文件。
ab+ 以二進制模式打開文件,並採用追加模式,對文件具有讀寫權限,如果文件存在,則文件指針位於文件的末尾(新寫入文件會位於已有內容之後);反之,則創建新文件。
'''
#open()
#file=open('a.txt') #默認打開模式 r 只讀模式,若無則報錯
file=open('測試文件\\testOpen_A.txt','w+') #指定打開模式 w+ 爲新建讀寫模式,若無則創建,若存在則替換覆蓋
file.write('這裏是第一次寫入內容') #write()方法按行寫入內容
#print(file) #通過file.reade()等讀取方法才能輸出內容
file.close()
file=open('測試文件\\testOpen_A.txt',encoding='utf-8') #指定打開文件的編碼格式,默認爲GBK編碼
#print(file) #通過file.reade()等讀取方法才能輸出內容
file.close()
#open()文件對象常用屬性
file.encoding #獲取對象的編碼方式
file.mode #獲取對象的打開模式
file.closed #獲取對象是否處於關閉狀態,返回布爾值
file.name #獲取對象打開的文件名
####################
#文件讀取操作
'''
1、read()
file.read([size])
其中,file 表示打開的文件對象;
size 作爲一個可選參數,用於指定要讀取的字符個數,如果省略,則默認一次性讀取所有內容。
2、readline()
file.readline([size])
file 爲打開的文件對象;
size 爲可選參數,用於指定讀取每一行時,一次最多讀取的字符數。
3、readlines()
用於讀取文件中的所有行,
它和調用不指定 size 參數的 read() 函數類似,只不過該函數返回是一個字符串列表,其中每個元素爲文件中的一行內容。
和 readline() 函數一樣,readlines() 函數在讀取每一行時,會連同行尾的換行符一塊讀取。
'''
#read()
#參數爲空,則默認讀取全部文件內容
#參數爲1, 則讀取1個字符/字節
#按字節/字符來讀取文件內容
#注意:(打開模式爲 B 二進制則按字節讀取;其他模式則按字符讀取)
f=open('測試文件\\testOpen_A.txt','r',True)
while True:
ch=f.read(1) #讀取一個字符,循環一直讀取
if not ch: #如果讀取不到內容,則退出;否則輸出讀取的內容。
break
# print(ch)
print(ch,end='') #自定義結束字符串味空 以此輸出原文原樣。默認爲換行符
f.close()
#read() #參數爲空,則默認讀取全部文件內容
f=open('測試文件\\testOpen_A.txt','r',True)
print(f.read())
f.close()
#read()後解碼輸出 打開模式爲二進制的bytes對象
f=open('測試文件\\testOpen_A.txt','rb',True) #用二進制模式打開文件,獲取得到bytes文件對象
#print(f.read())
print(f.read().decode('GBK')) #open()的默認encoding='GBK',注意需要一致編解碼。
f.close()
####################
#文件寫入操作
'''
1、file.write(string)
其中,file 表示已經打開的文件對象;string 表示要寫入文件的字符串(或字節串,僅適用寫入二進制文件中)。
2、file.writelines()
可以實現將字符串列表寫入文件中
'''
#write()
f=open('測試文件\\testOpen_A.txt','a+')
f.write('\n寫入第二行數據 追加寫入') #注意 a+爲追加讀寫模式在末尾,注意內容自行添加換行符\n
f.close()
#writelines()寫入列表結構,
#可寫入readlines()讀取返回的列表結構
f=open('測試文件\\testOpen_A.txt','r')
n=open('測試文件\\testOpen_B.txt','w+')
#print(f.readline())
#print(f.readlines())
n.writelines(f.readlines()) #readlines()讀取文件中的所有行,返回列表結構。 writelines()寫入列表結構
n.close()
f.close()
#美化輸出
import pprint
pprint.pprint(open('測試文件\\testOpen_A.txt').readlines())
####################
#使用文件的基本方法(讀取/寫入/迭代)
#通過readlines()讀取全部內容成列表後,修改列表元素,然後添加該列表,形成修改後的新的文本文件
f=open('測試文件\\testOpen_A.txt')
lines=f.readlines() #讀取文件所有行,返回列表結構
f.close()
lines[1]="通過提取f.readlines()的列表,然後對列表進行賦值操作。所以這裏進行了添加和新的修改。"
f=open('測試文件\\testOpen_D.txt','w+')
f.writelines(lines) #注意 a+爲追加讀寫模式在末尾,添加換行符\n
f.close()
print(lines)
#迭代文件內容的多重方式(read,readline,readlines)
#自建虛構的 內容處理函數
def process(string):
'''
用作展示 處理字符或行,可換做其他處理方法
'''
print('Processing: ',string)
#通過read方式讀取 單個字符 來循環迭代
with open('測試文件\\testOpen_A.txt') as f:
char=f.read(1)
while char:
process(char)
char=f.read(1)
with open('測試文件\\testOpen_A.txt') as f:
while True:
char=f.read(1)
if not char:
break
print(char,end='') #去除輸出結尾的默認換行符,從而達到連續輸出的目的。
#通過readline讀取 單行 來進行循環迭代
with open('測試文件\\testOpen_A.txt') as f:
while True:
char=f.readline()
if not char:
break
process(char)
#通過read 和 readlines 讀取全部內容,來進行循環迭代
with open('測試文件\\testOpen_A.txt') as f:
for char in f.read():
process(char)
with open('測試文件\\testOpen_A.txt') as f:
for char in f.readlines():
process(char)
#使用fileinput實現延遲 行迭代
import fileinput
for line in fileinput.input('測試文件\\testOpen_A.txt'):
process(line)
#文件迭代器
#注意:將讀取後的文件當做 迭代器 來使用,可循環,可操作,可list、序列解包、多重賦值等
with open('測試文件\\testOpen_A.txt') as f:
for line in f:
process(line)
#在不將 文件對象 賦值給 變量的情況下 迭代文件
for line in open('測試文件\\testOpen_A.txt'):
process(line)
#對迭代器做的事情基本上都可以對文件做。
#list方法將文件轉換成成字符串列表,效果等同於 readlines
list(open('測試文件\\testOpen_A.txt'))
#通過print的參數file指定,實現對文件近些 寫入操作
f=open('測試文件\\testOpen_E.txt','w')
print('First','line',file=f) #輸出內容到指定文件
print('Second','line',file=f)
print('Third','and final','line',file=f)
f.close()
#對文件讀取並序列解包,然後賦值應用
first,second,third=open('測試文件\\testOpen_E.txt') #給文件內容的每行進行賦值操作
print(first)
print(second)
print(third)
####################
#文件關閉操作
'''
file.close()
如果打開的文件對象不進行close()操作的話,會影響 譬如 os.remove('b.txt') 刪除文件等的操作
'''
####################
#文件指針
'''
實現對文件指針的移動,(以 b 模式打開,每個數據就是一個字節;以普通模式打開,每個數據就是一個字符)文件指針就標明瞭文件將要從文件的哪個位置開始讀起。
tell() 函數用於判斷文件指針當前所處的位置,
seek() 函數用於移動文件指針到文件的指定位置。
file.seek(offset[, whence])
參數whence: 可選參數,用於指定文件指針要放置的位置,
3 個選擇:0 代表文件頭(默認值)、1 代表當前位置、2 代表文件尾。
參數offset: 表示相對於 whence 位置文件指針的偏移量,正數表示向後偏移,負數表示向前偏移。
例如,當whence == 0 &&offset == 3(即 seek(3,0) ),表示文件指針移動至距離文件開頭處 3 個字符的位置;
當whence == 1 &&offset == 5(即 seek(5,1) ),表示文件指針向後移動,移動至距離當前位置 5 個字符處。
'''
f=open('測試文件\\testOpen_A.txt','r')
print(f.tell()) #輸出當前文件指針位置
print(f.read(3)) #按行讀取字符3個字符
print(f.tell()) #輸出當前文件指針位置
f.close()
f=open('測試文件\\testOpen_A.txt','rb')
print(f.tell()) #輸出當前文件指針位置
print(f.read(1)) #按行讀取1個字節,現文件指針位置在1
print(f.tell()) #輸出當前文件指針位置
f.seek(5) #設置文件指針位置至 5
print(f.tell()) #輸出當前文件指針位置
print(f.read(1)) #按行讀取1個字節
print(f.tell())
#將文件指針位置 向後移動到5個字符的位置
f.seek(5,1) #單設置文件指針至 當前指針向後移動5個字節 的位置
print(f.tell())
print(f.read(1))
print(f.tell())
#
f.seek(-1,2) #設置文件指針至 文件結尾向前移動1個字節 的位置
print(f.tell())
print(f.read(1))
print(f.tell())
f.close()
####################
#上下文管理器 同時包含__enter__() 和 __exit__()方法的對象就是上下文管理器
'''
http://c.biancheng.net/view/5319.html
同時包含__enter__() 和 __exit__() 兩個方法的對象就是上下文管理器
__enter__(self)
__exit__(self, exc_type, exc_value, exc_traceback)
構建上下文管理器,常見的有 2 種方式:基於類實現和基於生成器實現。
只要一個類實現了 __enter__() 和 __exit__() 這 2 個方法,程序就可以使用 with as 語句來管理它,
通過 __exit__() 方法的參數,即可判斷出 with 代碼塊執行時是否遇到了異常。
'''
with open('a.txt','a') as f:
f.write('\nPython大法')
#自定義類 實現上下文管理協議的類,並嘗試用 with as 語句來管理它:
class FkResource:
'''
自定義一個實現上下文管理協議的類,並嘗試用 with as 語句來管理它.
只要一個類實現了 __enter__() 和 __exit__() 這 2 個方法,程序就可以使用 with as 語句來管理它,
通過 __exit__() 方法的參數,即可判斷出 with 代碼塊執行時是否遇到了異常。
'''
def __init__(self,tag): #初始化構造器方法
self.tag=tag
print('構造器,初始化資源:{}'.format(tag))
def __enter__(self): #定義__enter__魔法方法,即with體之前執行的方法
print('[__enter__方法: {}]'.format(self.tag))
return 'fkit' #可以返回任何類型來測試該自建類方法
def __exit__(self, exc_type, exc_value, exc_traceback): #定義__exit__魔法方法,即with體之後執行的方法
print('[__exit__方法: {}]'.format(self.tag))
'''
參數exc_traceback 爲None,代表沒有異常
'''
if exc_traceback is None:
print('沒有異常,關閉資源')
else:
print('遇到異常,關閉資源')
return False #可以省略,默認返回None也被看成是False
with FkResource('孫悟空') as dr:
print(dr)
##測試異常
#with FkResource('白骨精'):
# print('[with代碼塊]異常之前的代碼////////////////')
# raise Exception
# print('[with代碼塊]異常之後的代碼----------------')
# =============================================================================
# #fileinput模塊
# #fileinput模塊能夠輕鬆的迭代一系列文本文件中的所有行
# #fileinput模塊提供了input函數,可以把多個輸入流合併在一起,然後進行一些循環操作等
# #可以在命令行運行腳本 命令如:python testNumberlines.py testNumberlines.py
# =============================================================================
####################
#探索fileinput模塊
import fileinput
help(fileinput)
fileinput.__doc__
fileinput.__file__
fileinput.__all__
dir(fileinput)
help(fileinput.filename) #返回正在讀取的文件的文件名。
help(fileinput.fileno) #返回當前文件的文件描述符(file descriptor),該文件描述符是一個整數。
help(fileinput.lineno) #返回當前讀取的行號。
help(fileinput.filelineno) #返回當前讀取的行在其文件中的行號。
help(fileinput.isfirstline) #返回當前讀取的行在其文件中是否爲第一行。
help(fileinput.isstdin) #返回最後一行是否從 sys.stdin 讀取。程序可以使用“-”代表從 sys.stdin 讀取。
help(fileinput.nextfile) #關閉當前文件,開始讀取下一個文件。
help(fileinput.close) #關閉 FileInput 對象。
####################
#常用屬性、方法、類等
help(fileinput.input)
'''
#fileinput.input(files="filename1, filename2, ...", inplace=False, backup='', bufsize=0, mode='r', openhook=None)
#此函數會返回一個 FileInput 對象
#參數files: 多個文件的路徑序列;
#參數inplace: 用於指定是否將標準輸出的結果寫回到文件,此參數默認值爲 False;
#參數backup: 用於指定備份文件的擴展名;
#參數bufsize: 指定緩衝區的大小,默認爲 0;
#參數mode: 打開文件的格式,默認爲 r(只讀格式);
#參數openhook: 控制文件的打開方式,例如編碼格式等。
'''
#通過input函數創建了 FileInput 對象之後,即可通過 for 循環來遍歷文件的每一行。
#在for循環裏即可通過方法來進行相關操作
'''
#fileinput.filename() 返回正在讀取的文件的文件名。
#fileinput.fileno() 返回當前文件的文件描述符(file descriptor),該文件描述符是一個整數。
#fileinput.lineno() 返回當前讀取的行號。
#fileinput.filelineno() 返回當前讀取的行在其文件中的行號。
#fileinput.isfirstline() 返回當前讀取的行在其文件中是否爲第一行。
#fileinput.isstdin() 返回最後一行是否從 sys.stdin 讀取。程序可以使用“-”代表從 sys.stdin 讀取。
#fileinput.nextfile() 關閉當前文件,開始讀取下一個文件。
#fileinput.close() 關閉 FileInput 對象。
'''
####################
#示例1
'''
不支持中文問題
通過參數打開模式 mode='rb' 即二進制模式打開,然後輸出執行解碼utf-8,輸出中文成功
'''
import fileinput
for line in fileinput.input(files=('testFileinput_A.txt', 'testFileinput_B.txt'),mode='rb'): # 一次讀取多個文件
print(fileinput.filename(), fileinput.filelineno(), line.decode('utf-8')) # 輸出文件名,當前行在當前文件中的行號,行內容。
fileinput.close() # 關閉文件流
with fileinput.input(files=('testA.txt','testB.txt'),mode='rb') as f:
for line in f:
print(line.decode('utf-8'))
####################
#示例2 可改寫格式,然後即可用於給文件進行格式添加
#自建腳本文件 testFileinput_格式添加.py 在程序右側添加行號格式化
#然後在控制檯運行這個腳本程序,並將其作爲參數傳入。
#命令如:python testFileinput_格式添加.py testFileinput_格式添加.py
'''
出現解碼問題
通過參數打開模式 mode='rb' 即二進制模式打開,然後輸出執行解碼utf-8,輸出中文成功
'''
import fileinput
for line in fileinput.input(mode='rb',inplace=False): #inplace可選擇是否本地修改
line=line.rstrip() #清洗右側空白字符
num=fileinput.lineno() #輸出當前文件的當前行號
#print格式設置 冒號前爲輸出對象,冒號後面:整數部分代表寬度,符號<代表左對齊,d代表十進制格式
print('{:<50} # {:2d}'.format(line.decode('utf-8'),num))
fileinput.close()
# =============================================================================
# #linecache模塊
#
# #linecache模塊允許從python源文件中(所有utf-8文件)隨機讀取指定行,並在內部使用緩存優化存儲。
# #由於該模塊主要被設計成讀取 Python 源文件,因此它會用 UTF-8 字符集來讀取文本文件。
# #實際上,使用 linecache 模塊也可以讀取其他文件,只要該文件使用了 UTF-8 字符集存儲。
# =============================================================================
'''
#注意:
1、非UTF-8字符集存儲的文件讀取不出來問題。
'''
import linecache
import random
##################
#探索模塊
help(linecache)
linecache.__doc__
linecache.__file__
linecache.__all__
dir(linecache)
help(linecache.getline) #獲取 文件filename 的 第lineno行 內容 參數(filename,lineno)
help(linecache.getlines) #獲取 問價filename 的全部行,返回列表結構。
help(linecache.clearcache)
help(linecache.checkcache)
###################
#常用屬性、函數、類
#行數index從1開始,而非0
print(linecache.getline(random.__file__,3)) #讀取random源文件的第三行內容
print(linecache.getlines(random.__file__)) #讀取random源文件的所有行,返回列表結構
#注意非UTF-8字符集存儲的文件讀取不出來問題。
print(linecache.getline('F:\\SpyderXIANGMUWENJIANJIA\\編程基礎\\Py基礎標準庫及應用\Py基礎標準庫time.py',2))
print(linecache.getlines('F:\\SpyderXIANGMUWENJIANJIA\\編程基礎\\Py基礎標準庫及應用\Py基礎標準庫time.py'))