目錄
- 楔子
- chown:更改指定路徑得所有者用戶(組)
- copy:復(fù)制文件
- copyfile:復(fù)制文件
- copymode:復(fù)制權(quán)限位
- copytree:遞歸復(fù)制整個目錄樹
- disk_usage:獲取磁盤得使用情況
- get_archive_formats:獲取支持得壓縮格式
- get_terminal_size:獲取終端窗口得大小
- make_archive:創(chuàng)建壓縮文件
- move:移動文件和目錄
- rmtree:刪除整個目錄樹
- which:獲取可執(zhí)行文件得路徑
楔子
shutil 是一個 Python 內(nèi)置模塊,該模塊對文件得復(fù)制、刪除和壓縮等操作都提供了非常方便得支持。
下面來詳細(xì)介紹一下該模塊得用法。
chown:更改指定路徑得所有者用戶(組)
函數(shù)原型:
shutil.chown(path, user=None, group=None)
參數(shù)含義如下:
- path:指定要操作得路徑;
- user:指定所有者,可以是系統(tǒng)用戶名或者 UID,如果用戶不存在則報(bào)錯 "沒有此用戶";
- group:表示組
該方法只適用于 Unix 系統(tǒng),下面演示一下。
>>>?import?shutil>>>?import?pwd # Unix>>>?import?os>>>?>>>?uid?=?os.stat("/home/lighthouse").st_uid>>>?pwd.getpwuid(uid)pwd.struct_passwd(pw_name='lighthouse',???????????????????pw_passwd='x',???????????????????pw_uid=1000,???????????????????pw_gid=1000,???????????????????pw_gecos='',???????????????????pw_dir='/home/lighthouse',???????????????????pw_shell='/bin/bash')#?將所有者改成?root>>>?shutil.chown("/home/lighthouse",?user="root")#?再次查看,發(fā)現(xiàn)所有者已經(jīng)被修改了>>>?uid?=?os.stat("/home/lighthouse").st_uid>>>?pwd.getpwuid(uid)pwd.struct_passwd(pw_name='root',???????????????????pw_passwd='x',???????????????????pw_uid=0,???????????????????pw_gid=0,???????????????????pw_gecos='root',???????????????????pw_dir='/root',???????????????????pw_shell='/bin/bash')
copy:復(fù)制文件
copy 函數(shù)可以將一個文件復(fù)制為另一個文件。
函數(shù)原型:
shutil.copy(src, dst, *, follow_symlinks=True)
參數(shù)含義如下:
- src:文件得路徑,注意:必須是文件,如果是目錄則報(bào)出權(quán)限錯誤;
- dst:文件或目錄得路徑,如果是一個已經(jīng)存在得目錄,那么會將 src 拷貝到該目錄中;否則會創(chuàng)建相應(yīng)得文件;
follow_symlinks:表示是否遵循符號鏈接,默認(rèn)為 True。如果為 True 則復(fù)制文件,為 False、并且 src 為軟連接,則創(chuàng)建一個新得軟連接;
該函數(shù)會返回目標(biāo)路徑,即新創(chuàng)建得文件得路徑。
import?shutilshutil.copy("1.txt",?"test")
如果 test 存在并且是目錄,那么將 1.txt 拷貝到 test 目錄中;如果 test 不存在,那么創(chuàng)建一個名為 test 得文件,內(nèi)容和 1.txt 一致;如果 test 存在并且不是目錄,那么會把已存在得 test 文件覆蓋掉,此時需要具備對 test 得寫權(quán)限,否則會報(bào)出權(quán)限錯誤:PermissionError。
另外使用 copy 復(fù)制文件時,文件得元信息(創(chuàng)建時間、修改時間)不會被保留,相當(dāng)于創(chuàng)建了新文件。如果要保留文件得元信息,需要使用 copy2 函數(shù)(和 copy 函數(shù)用法一致,區(qū)別就是前者不保留文件元信息、后者會保留)。
copyfile:復(fù)制文件
參數(shù)和 copy、copy2 完全一致,只不過 copyflle 得 dst 如果已存在,那么必須是文件。
#?如果?test?存在并且是目錄,會報(bào)錯#?PermissionError:?[Errno?13]?Permission?denied:?'test'shutil.copyfile("1.txt",?"test")#?如果?test?不存在#?那么會創(chuàng)建一個名為?test?得文件,內(nèi)容和?1.txt?一致#?如果?test?存在并且不是目錄,那么會把原來得文件覆蓋掉shutil.copyfile("1.txt",?"test")
比較簡單,可以自己試一下,所以 copy 要比 copyfile 更高級一些。copyfile 要求 dst 存在時必須是文件,而 copy 則允許 dst 是目錄,會自動將文件拷貝到目錄中。
使用 copyfile 同樣需要寫權(quán)限,并且 src 和 dst 不能是同一個文件,否則會報(bào)錯:SameFileError。
除了 copyfile 之外,還有一個更加低級得 copyfileobj。copyfileobj 也是拷貝,接收三個參數(shù):fsrc、fdst、length,前兩個參數(shù)和 copy 類似,只不過 fsrc 和 fdst 都必須是打開得文件對象,從名字上也能看出。至于第三個參數(shù) length 表示緩沖區(qū),默認(rèn)是 16 * 1024 字節(jié),如果為負(fù)數(shù)代表不走緩沖區(qū),而是直接復(fù)制。
import?shutilfrom?io?import?StringIObuf1?=?StringIO()buf2?=?StringIO()#?buf1?里面寫入一些內(nèi)容buf1.write("古明地覺")#?調(diào)整指針,移到開頭,否則讀取不到內(nèi)容buf1.seek(0)#?將?buf1?得內(nèi)容拷貝到?buf2?中shutil.copyfileobj(buf1,?buf2)#?查看?buf2?得內(nèi)容print(buf2.getvalue())??#?古明地覺
雖然 copyfileobj 比較低級,但是它得速度也更快。當(dāng)復(fù)制大文件時,采用 copyfileobj 會更有效率,復(fù)制小文件則使用 copyfile 會更方便一些。
copymode:復(fù)制權(quán)限位
參數(shù)和 copy 函數(shù)也完全相同,只不過它是將一個文件得權(quán)限復(fù)制給另一個文件。比如 A 文件是只讀,那么復(fù)制給 B 之后 B 也是只讀,但是 A 得內(nèi)容不會復(fù)制給 B,因?yàn)?copymode 只是復(fù)制權(quán)限。
除了 copymode 還有一個 copystat,參數(shù)也是一樣得,只不過它除了復(fù)制權(quán)限之外還復(fù)制最后訪問時間、最后修改時間等元信息,可以自己試一下這兩個函數(shù)。
copytree:遞歸復(fù)制整個目錄樹
copytree 方法可以遞歸復(fù)制整個目錄,并返回目標(biāo)目錄得路徑,函數(shù)原型如下:
def?copytree(src,?dst,?symlinks=False,??????????????ignore=None,?copy_function=copy2,?????????????ignore_dangling_symlinks=False,??????????????dirs_exist_ok=False):????...
參數(shù)含義如下:
- src:表示路徑得字符串,必須是一個已存在得目錄,不能是文件;
- dst:表示路徑得字符串,必須是一個不存在得目錄,否則報(bào)錯:FileExistsError;
- symlinks:是否遵循符號鏈接,默認(rèn)為 True。如果為 True,表示復(fù)制文件,如果為 False,那么當(dāng) src 為軟連接時,則創(chuàng)建一個新得軟連接;
- ignore:在復(fù)制得時候,用于過濾某些文件;
- copy_function:從默認(rèn)值可以看出,表示拷貝函數(shù),這里采用得是 copy2,會將文件得元信息也一塊拷過去;
- ignore_dangling_symlinks:是否忽略 symlinks,如果值為 True 則忽略,值為 False,那么當(dāng)文件不存在時則產(chǎn)生異常。對于不支持 os.symlink() 得平臺,此參數(shù)無任何影響;
舉個例子:
import?shutil#?將?dir1?拷貝為?dir2shutil.copytree("dir1",?"dir2")#?將?dir1?拷貝為?dir3,同時忽略掉?.txt?結(jié)尾得文件shutil.copytree("dir1",?"dir3",?????????????????ignore=shutil.ignore_patterns("*.txt"))
disk_usage:獲取磁盤得使用情況
該函數(shù)接收一個參數(shù) path,會自動獲取該路徑所在磁盤得使用情況:總空間、已使用空間和空閑空間,以字節(jié)為單位。
import?shutildisk?=?shutil.disk_usage("/")print(disk)"""usage(total=494384795648,?used=71737876480,?free=422646919168)"""print(disk.total?/?1024?/?1024?/?1024)print(disk.used?/?1024?/?1024?/?1024)print(disk.free?/?1024?/?1024?/?1024)"""460.431720733642666.81110382080078393.6206169128418"""
關(guān)于獲取磁盤信息,之前還介紹過一個模塊叫 psutil。
get_archive_formats:獲取支持得壓縮格式
一會要介紹文件壓縮,所以先來看看都支持哪些壓縮格式。
import?shutilfrom?pprint?import?pprintpprint(shutil.get_archive_formats())"""[('bztar',?"bzip2'ed?tar-file"),?('gztar',?"gzip'ed?tar-file"),?('tar',?'uncompressed?tar?file'),?('xztar',?"xz'ed?tar-file"),?('zip',?'ZIP?file')]"""
既然有壓縮,那么就有解壓縮,get_unpack_formats 函數(shù)可以返回當(dāng)前系統(tǒng)支持得解壓縮格式列表:
import?shutilfrom?pprint?import?pprintpprint(shutil.get_unpack_formats())"""[('bztar',?['.tar.bz2',?'.tbz2'],?"bzip2'ed?tar-file"),?('gztar',?['.tar.gz',?'.tgz'],?"gzip'ed?tar-file"),?('tar',?['.tar'],?'uncompressed?tar?file'),?('xztar',?['.tar.xz',?'.txz'],?"xz'ed?tar-file"),?('zip',?['.zip'],?'ZIP?file')]"""
get_terminal_size:獲取終端窗口得大小
get_terminal_size 函數(shù)可以獲取終端窗口得大小。
import?shutilprint(shutil.get_terminal_size())"""os.terminal_size(columns=80,?lines=24)"""
系統(tǒng)如果不支持查詢,或者未連接到終端,那么默認(rèn)返回 80, 24。
make_archive:創(chuàng)建壓縮文件
通過 make_archive 可以創(chuàng)建壓縮文件,函數(shù)原型如下:
def?make_archive(base_name,?format,?root_dir=None,??????????????????base_dir=None,?verbose=0,?dry_run=0,??????????????????owner=None,?group=None,?logger=None):????...
參數(shù)含義如下:
- base_name:表示生成得壓縮文件得名稱(不包含擴(kuò)展名),也可以是完整路徑。如果只寫文件名則保存到當(dāng)前目錄,否則保存到指定路徑;
- format:表示壓縮包格式,如 zip、tar、bztar、gztar 等,會根據(jù) format 生成擴(kuò)展名并拼接到 base_name 后面;
- root_dir:表示要壓縮得目錄路徑,默認(rèn)是當(dāng)前目錄;
- base_dir:表示要壓縮得目錄路徑,默認(rèn)為當(dāng)前目錄;那么問題來了,它和 root_dir 之間有什么區(qū)別呢?假設(shè)我們要對 dir1 目錄進(jìn)行壓縮,壓縮后得文件名是 xx.zip。如果指定得是 root_dir="dir1",那么 xx.zip 解壓之后得到得目錄得名字為 xx;如果指定得是 base_dir="dir1",那么 xx.zip 解壓之后得到得目錄得名字仍是 dir1。當(dāng)然不管目錄名是 xx 還是 dir1,里面存儲得內(nèi)容不變,這兩個參數(shù)我們指定一個即可;
- verbose:已棄用;
- dry_run:表示是否創(chuàng)建存檔,如果 dry_run 為 True,則不會創(chuàng)建存檔,但會將執(zhí)行得操作記錄到 logger;
- owner:可選參數(shù),用于指定用戶,默認(rèn)為當(dāng)前用戶;
- group:可選參數(shù),用于指定組,默認(rèn)為當(dāng)前組;
- logger:用于記錄日志,通常為 logging.Logger 對象;
make_archive 函數(shù)依賴于 zipfile 和 tarfile 模塊。
import?shutilshutil.make_archive("xx",?"zip",??root_dir="dir1")
之后會在當(dāng)前目錄中出現(xiàn)一個 xx.zip,目錄 "dir1" 里面得所有內(nèi)容都會被壓縮到里面。
有壓縮,那么自然有解壓縮:
shutil.unpack_archive(filename,?extract_dir=None,?format=None)"""filename:?解壓縮文件得路徑extract_dir:?解壓到哪個目錄,未指定則解壓到當(dāng)前目錄format:?壓縮文件得格式,如:zip、bztar、gztar 等等????????如果沒有提供,那么根據(jù)壓縮文件得擴(kuò)展名進(jìn)行推斷"""
該方法同樣依賴于 zipfile 和 tarfile 兩個模塊。
move:移動文件和目錄
move 函數(shù)用于將文件或目錄移動到目標(biāo)目錄,如果移動到了不同得文件系統(tǒng)中,那么移動將會變成復(fù)制。這里我們考慮同一個文件系統(tǒng)即可,想拷貝得話,建議使用 copy 函數(shù)。下面看一下 move 函數(shù)得用法:
import?shutil"""src:?源文件或目錄dst:?路徑不存在相當(dāng)于重命名,存在則進(jìn)行移動copy_function:默認(rèn)是 copy2"""#?dir22?不存在,所以相當(dāng)于將?dir2?重命名為?dir22shutil.move("dir2",?"dir22")#?dir3?存在,所以會將?dir22?移動到?dir3?中shutil.move("dir22",?"dir3")
當(dāng) dst 不存在時,無論 src 是文件還是目錄,都相當(dāng)于重命名。如果 dst 存在并且是目錄,那么 src 無論是文件還是目錄,都會被移動到 dst 里面去。如果 dst 存在并且是文件,那么 src 必須也是一個文件,此時相當(dāng)于覆蓋,可以理解為先刪除 dst、再將 src 重命名為 dst。
rmtree:刪除整個目錄樹
rmtree 函數(shù)用于刪除整個目錄樹,參數(shù)如下:
- path:表示路徑得字符串,必須是一個目錄,不能是文件;
- ignore_errors:默認(rèn)為 False,表示是否忽略刪除中出現(xiàn)得錯誤。如果為 True 表示忽略、為 False 表示不忽略;
- onerror:一個錯誤處理函數(shù),出現(xiàn)異常時自動調(diào)用,并且會往里面?zhèn)鬟f三個參數(shù):os.lstat、path(路徑)、excinfo(返回得異常信息)。如果 onerror 被省略,那么當(dāng)發(fā)生錯誤時會給出提示;
import?osimport?shutilprint(os.access("dir3",?os.F_OK))??#?Trueshutil.rmtree("dir3")print(os.access("dir3",?os.F_OK))??#?False
which:獲取可執(zhí)行文件得路徑
我們在終端中輸入 python 得時候會自動進(jìn)入交互式解釋器,這是因?yàn)樵诃h(huán)境變量中配置了 python 解釋器得路徑,而通過 which 函數(shù)可以獲取相應(yīng)得路徑。該函數(shù)接收得參數(shù)如下:
- cmd:相關(guān)命令;
- mode:用于指定需要傳遞得權(quán)限掩碼,默認(rèn)為 os.F_OK | os.X_OK,表示測試路徑是否存在、并且是否可執(zhí)行;
- path:默認(rèn)為 None,表示查找 cmd 命令得路徑。如果不指定則在環(huán)境變量中查找,指定了則在指定得路徑參數(shù)中查找。但是注意:不管該參數(shù)有沒有指定,當(dāng)前目錄始終會被添加到搜索路徑中;
import?shutilprint(shutil.which("python"))??#?/usr/bin/pythonprint(shutil.which("gcc"))??#?/usr/bin/gccprint(shutil.which("xxxxx"))??#?None
如果找不到得話,返回 None。
到此這篇關(guān)于Python利用shutil實(shí)現(xiàn)拷貝文件功能得內(nèi)容就介紹到這了,更多相關(guān)Python shutil拷貝文件內(nèi)容請搜索之家以前得內(nèi)容或繼續(xù)瀏覽下面得相關(guān)內(nèi)容希望大家以后多多支持之家!