1. shutil高層檔案操作
shutil模塊包括一些高層檔案操作,如復制和歸檔,
1.1 復制檔案
copyfile()將源檔案的內容復制到目標檔案,如果沒有權限寫目標檔案,則會產生IOError,
import glob import shutil print('BEFORE:', glob.glob('shutil_copyfile.*')) shutil.copyfile('shutil_copyfile.py', 'shutil_copyfile.py.copy') print('AFTER:', glob.glob('shutil_copyfile.*'))
由于這個函式會打開輸入檔案進行讀取,而不論其型別,所以某些特殊檔案(如UNIX設備節點)不能用copyfile()復制為新的特殊檔案,

copyfile()的實作使用了底層函式copyfileobj(),copyfile()的引數是檔案名,但copyfileobj()的引數是打開的檔案句柄,還可以有第三個引數(可選):讀入塊使用的一個緩沖區長度,
import io import os import shutil import sys class VerboseStringIO(io.StringIO): def read(self, n=-1): next = io.StringIO.read(self, n) print('read({}) got {} bytes'.format(n, len(next))) return next lorem_ipsum = '''Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vestibulum aliquam mollis dolor. Donec vulputate nunc ut diam. Ut rutrum mi vel sem. Vestibulum ante ipsum.''' print('Default:') input = VerboseStringIO(lorem_ipsum) output = io.StringIO() shutil.copyfileobj(input, output) print() print('All at once:') input = VerboseStringIO(lorem_ipsum) output = io.StringIO() shutil.copyfileobj(input, output, -1) print() print('Blocks of 256:') input = VerboseStringIO(lorem_ipsum) output = io.StringIO() shutil.copyfileobj(input, output, 256)
默認行為是使用大資料塊讀取,使用-1會一次讀入所有輸入,或者也可以使用其他正數,這會設定特定的塊大小,下面這個例子將使用多個不同的塊大小來展示效果,

類似于UNIX命令列工具cp,copy()函式會用同樣的方式解釋輸出名,如果指定的目標指示一個目錄而不是一個檔案,則會使用源檔案的基名在該目錄中創建一個新檔案,
import glob import os import shutil os.mkdir('example') print('BEFORE:', glob.glob('example/*')) shutil.copy('shutil_copy.py', 'example') print('AFTER :', glob.glob('example/*'))
一同復制檔案的權限與內容,

copy2()的作業類似于copy(),不過會在復制到新檔案的元資料中包含訪問的修改時間,
import os import shutil import time def show_file_info(filename): stat_info = os.stat(filename) print(' Mode :', oct(stat_info.st_mode)) print(' Created :', time.ctime(stat_info.st_ctime)) print(' Accessed:', time.ctime(stat_info.st_atime)) print(' Modified:', time.ctime(stat_info.st_mtime)) os.mkdir('example') print('SOURCE:') show_file_info('shutil_copy2.py') shutil.copy2('shutil_copy2.py', 'example') print('DEST:') show_file_info('example/shutil_copy2.py')
這個新檔案的所有特性讀與原檔案完全相同,

1.2 復制檔案元資料
默認的,在UNIX下創建一個新的檔案時,它會根據當前用戶的umask接受權限,要把權限從一個檔案復制到另一個檔案,可以使用copymode(),
import os import shutil with open('file_to_change.txt', 'wt') as f: f.write('content') os.chmod('file_to_change.txt', 0o444) print('BEFORE:', oct(os.stat('file_to_change.txt').st_mode)) shutil.copymode('shutil_copymode.py', 'file_to_change.txt') print('AFTER :', oct(os.stat('file_to_change.txt').st_mode))
這個示例腳本創建了一個要修改的檔案,然后使用copymode()將腳本的權限復制到示例檔案,

要為檔案復制到其他元資料,可以使用copystat(),
import os import shutil import time def show_file_info(filename): stat_info = os.stat(filename) print(' Mode :', oct(stat_info.st_mode)) print(' Created :', time.ctime(stat_info.st_ctime)) print(' Accessed:', time.ctime(stat_info.st_atime)) print(' Modified:', time.ctime(stat_info.st_mtime)) with open('file_to_change.txt', 'wt') as f: f.write('content') os.chmod('file_to_change.txt', 0o444) print('BEFORE:') show_file_info('file_to_change.txt') shutil.copystat('shutil_copystat.py', 'file_to_change.txt') print('AFTER:') show_file_info('file_to_change.txt')
使用copystat()只會復制與檔案關聯的權限和日期,

1.3 處理目錄樹
shutil包含3個函式來處理目錄樹,要把一個目錄從一個位置復制到另一個位置,可以使用copytree(),這個函式會遞回遍歷源目錄樹,將檔案復制到目錄位置,目標目錄必須不存在,
import glob import pprint import shutil print('BEFORE:') pprint.pprint(glob.glob('/tmp/example/*')) shutil.copytree('../shutil', 'C') print('\nAFTER:') pprint.pprint(glob.glob('/*'))
symlinks引數控制符號鏈接作為鏈接復制或檔案復制,默認的會將內容復制到新檔案,如果這個選項為true,則會在目標樹中創建新的符號鏈接,

copytree()接受兩個callabe引數來控制它的行為,呼叫ignore引數時要提供復制的各個目錄或子目錄的名,以及一個目錄內容串列,這個函式應當回傳待復制元素的一個串列,另外呼叫copy_function引數來具體復制檔案,
import glob import pprint import shutil def verbose_copy(src, dst): print('copying\n {!r}\n to {!r}'.format(src, dst)) return shutil.copy2(src, dst) print('BEFORE:') pprint.pprint(glob.glob('/tmp/example/*')) print() shutil.copytree( 'E:/pythondaima/1l', '/tmp/example', copy_function=verbose_copy, ignore=shutil.ignore_patterns('*.py'), ) print('\nAFTER:') pprint.pprint(glob.glob('/tmp/example/*'))
在這個例子中,使用了ignore_patterns()來創建一個ignore函式,要求不復制Python源檔案,verbose_copy()首先列印復制檔案時的檔案名;然后使用copy2()(即默認的復制函式)來建立副本,

要洗掉一個目錄以及其中的內容,可以使用rmtree(),
import glob import pprint import shutil print('BEFORE:') pprint.pprint(glob.glob('/tmp/example/*')) shutil.rmtree('/tmp/example') print('\nAFTER:') pprint.pprint(glob.glob('/tmp/example/*'))
默認的,如果出現錯誤,則會作為例外拋出,不過如果第二個引數為true,則可以忽略這些錯誤,可以在第三引數中提供一個特殊的錯誤處理函式,

要把一個檔案或目錄從一個位置移動到另一個位置,可以使用move(),
import glob import shutil with open('example.txt', 'wt') as f: f.write('contents') print('BEFORE: ', glob.glob('example*')) shutil.move('example.txt', 'example.out') print('AFTER : ', glob.glob('example*'))
其語意與UNIX命令mv類似,如果源和目標都在同一個檔案系統中,則會重命名源檔案,否則,源檔案會被復制到目標檔案,然后被洗掉,

1.4 查找檔案
which()函式會掃描一個搜索路徑以查找一個命名檔案,典型的用法是在環境變數PATH定義的shell搜索路徑中查找一個可執行程式,
import shutil print(shutil.which('python')) print(shutil.which('time')) print(shutil.which('java'))
如果無法找到與搜索引數匹配的檔案,則which()回傳None,

1.5 歸檔
Python的標準庫包含很多模塊來管理歸檔檔案,如tarfile和zipfile,另外,shutil中還提供了很多更高層函式來創建和解壓歸檔檔案,get_archive_formats()回傳當前系統上支持的所有格式的名字和描述,
import shutil for format, description in shutil.get_archive_formats(): print('{:<5}: {}'.format(format, description))
支持的格式取決于有哪些模塊和底層庫,因此,根據這個例子在哪里運行,它的輸出可能會有變化,

shutil維護了一個格式注冊表,可以在當前系統上解包;可以通過get_unpack_formats()訪問這個注冊表,
import shutil for format, exts, description in shutil.get_unpack_formats(): print('{:<5}: {}, names ending in {}'.format( format, description, exts))
shutil管理的注冊表不同于創建歸檔所用的注冊表,因為它還包括對應各種格式的常見檔案擴展名,解壓縮歸檔檔案的函式使用這個注冊表來根據檔案擴展名猜測應當使用哪種格式,

1.6 檔案系統空間
完成一個長時間運行的可能耗盡可用的空間的操作之前,最好先檢查本地檔案系統,來看看有多少可用的空間,這會很有用,disk_usage()會回傳一個元組,包括總空間、當前正在使用的空間以及未用的空間(自由空間),
import shutil total_b, used_b, free_b = shutil.disk_usage('.') gib = 2 ** 30 # GiB == gibibyte gb = 10 ** 9 # GB == gigabyte print('Total: {:6.2f} GB {:6.2f} GiB'.format( total_b / gb, total_b / gib)) print('Used : {:6.2f} GB {:6.2f} GiB'.format( used_b / gb, used_b / gib)) print('Free : {:6.2f} GB {:6.2f} GiB'.format( free_b / gb, free_b / gib))
disk_usage()回傳的值以位元組為單位,所以這個示例程式在列印之前先把它轉換為更可讀的一些單位,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/175713.html
標籤:Python
上一篇:Python——專案-小游戲
