Published 4月 20, 2020 by with 0 comment

Automate The Boring Stuff With Python - Chapter 9 – 組織文件

今天是看這本書Automate the Boring Stuff with Python(Python編程快速上手--讓繁瑣工作自動化)
第9章節(Reading and Writing Files)所做的練習

這章主要講使用Python對所有文件重命名, 拷貝, 刪除, 複製等動作.


shutil模組提供了一些涵數, 能用於複製文件或整個文件夾.

shutil.copy(source, destination) 用來將路徑source的文件複製到路徑destination.
若destination為文件名, 它將作為被複製文件的新檔名.
>>> import os, shutil
>>> os.chdir('D:\Tech\Blog\Python\Automate The Boring Stuff With Python\Chapter 9')
>>> shutil.copy('9_1_1.txt', '9_1_1_copy.txt')
'9_1_1_copy.txt'
>>>


shutil.copytree(source, destination) 用來將路徑source的文件夾及其子資料夾下的文件, 整個複製到路徑destination文件夾.
>>> shutil.copytree('D:\Tech\Blog\Python\Automate The Boring Stuff With Python\Chapter 9', 'D:\Tech\Blog\Python\Automate The Boring Stuff With Python\Chapter 9\Backup')
'D:\\Tech\\Blog\\Python\\Automate The Boring Stuff With Python\\Chapter 9\\Backup'
>>>


shutil.move(source, destination) 用來將路徑source的文件夾及其子資料夾下的文件, 整個移動到路徑destination文件夾.
若目的地為文件夾且已存在, 則移動到該文件夾
若目的地為文件夾且不存在, 則該文件會被移動且無副檔名(小心)
若目的地為文件且已存在, 則複寫到該文件
若目的地為文件且不存在, 則移動到該文件
>>> shutil.move('D:\Tech\Blog\Python\Automate The Boring Stuff With Python\Chapter 9\Backup', 'D:\Tech\Blog\Python\Automate The Boring Stuff With Python\Chapter 9\Backup-1')
'D:\\Tech\\Blog\\Python\\Automate The Boring Stuff With Python\\Chapter 9\\Backup-1'
>>>


os.unlink(path) 用來刪除將路徑path的文件
os.rmdir(path) 用來刪除將路徑path的文件夾, 此文件夾必須為空
shutil.retree(path) 用來刪除將路徑path的文件夾及其子資料夾下的所有文件 (很危險)

因為上列指令很危險, 在實行之前, 可以做些保險措施:

>>> import os, shutil
# os.listdir(path) 用列表(list)的方式, 列出該目錄中所有目錄及文件名
>>> for fileName in os.listdir('D:\\Tech\\Blog\\Python\\Automate The Boring Stuff With Python\\Chapter 9\\Backup-1'):
    if fileName.endswith('.txt'):    # 列出副檔名為.txt的文件
        #os.unlink(fileName)    # 先把os.unlink() 注釋起來, 等確定好文件名之後, 再移除注釋
        print(fileName)

       
8_2.txt
8_2_3.txt
9_1_1.txt
9_1_1_copy.txt
Chapter_9.txt
>>>


send2trash.send2trash() 是第三方模塊, 需另外安裝. 它把檔案移去垃圾筒, 而不是直接刪除. 相對安全許多.
>>> import send2trash
>>> send2trash.send2trash('test.txt')
>>>

os.walk() 會在每一層目錄返回三個值, 然後進入子目錄, 再返回三個值, 並直到最後一層.
1. 當前文件夾的名稱
2. 以列表(List)的方式返回子文件夾名稱
3. 以列表(List)的方式返回文件名稱
>>> import os
>>> for folderName, subFolders, fileNames in os.walk('D:\\Tech\\Blog\\Python\\Automate The Boring Stuff With Python\\Chapter 9'):
    print('The current folder: ' + folderName)
    print('The subfolder: ' + str(subFolders))
    print('The filename: ' + str(fileNames))

   
The current folder: D:\Tech\Blog\Python\Automate The Boring Stuff With Python\Chapter 9
The subfolder: ['Backup-1']
The filename: ['8_2.txt', '8_2_3.txt', '8_9_3.py', '9_1_1.txt', '9_1_1_copy.txt', 'Chapter_9.txt']
The current folder: D:\Tech\Blog\Python\Automate The Boring Stuff With Python\Chapter 9\Backup-1
The subfolder: []
The filename: ['8_2.txt', '8_2_3.txt', '8_9_3.py', '9_1_1.txt', '9_1_1_copy.txt', 'Chapter_9.txt']
>>> 


zipfile.ZipFile() 向它傳入一個字符串, 為zip文件的文件名.
.namelist() 可以返回zip文件中包含的所有目錄及文件.
>>> import os, zipfile
>>> os.chdir('D:\Tech\Blog\Python\Automate The Boring Stuff With Python\Chapter 9')
>>> exampleZip = zipfile.ZipFile('9_3_1.zip')
>>> exampleZip.namelist()    # 返回zip文件中包含的所有目錄及文件.
['9_3_1/', '9_3_1/test0.txt', '9_3_1/Test1/', '9_3_1/Test1/test1.txt']
>>> spamInfo = exampleZip.getinfo('9_3_1/test0.txt')    # 返回特定文件自己的屬性
['9_3_1/', '9_3_1/test0.txt', '9_3_1/Test1/', '9_3_1/Test1/test1.txt']
>>> spamInfo.file_size    # 該文件的原始大小
126
>>> spamInfo.compress_size    # 該文件壓縮之後的大小
34
>>> exampleZip.close()    # 關閉zip檔案
>>>


.extractall() 可以解壓縮文件, 並放到當前的目錄
>>> import zipfile, os
>>> os.chdir('D:\Tech\Blog\Python\Automate The Boring Stuff With Python\Chapter 9')
>>> exampleZip.extractall('.\9_3_2_test')    # 可將解壓後的文檔放在指定的目錄.
>>> exampleZip.close()
>>> os.listdir('D:\Tech\Blog\Python\Automate The Boring Stuff With Python\Chapter 9')
['9_1_1.txt', '9_1_1_copy.txt', '9_3_1', '9_3_1.zip', '9_3_2.zip', '9_3_2_test', 'Backup-1', 'Chapter_9.txt']
>>> exampleZip.close()
>>>


zipfile.ZipFile() 用'w'寫入模式, 可以壓縮該路徑所指的文檔. 用'a'添加模式, 可將文件加入該路徑所指的壓縮檔.
>>> import os, zipfile
>>> os.chdir('D:\Tech\Blog\Python\Automate The Boring Stuff With Python\Chapter 9')
>>> newZip = zipfile.ZipFile('9_3_3.zip', 'w')    # 用'w'寫入模式
>>> newZip.write('9_3_3-1.txt', compress_type=zipfile.ZIP_DEFLATED)
>>> newZip.close()
>>> newZip.namelist()    # 檢查壓縮檔內容
['9_3_3-1.txt']
>>>
>>> newZip = zipfile.ZipFile('9_3_3.zip', 'a')    # 用'a'添加模式
>>> newZip.write('9_3_3-2.txt', compress_type=zipfile.ZIP_DEFLATED)
>>> newZip.close()
>>> newZip.namelist()    # 檢查壓縮檔內容
['9_3_3-1.txt', '9_3_3-2.txt']
>>>



章節9習題, 用Notepad++打下列的程式碼,
另存為9_8_1.py. 我附上中文注釋方便好讀.
# -*- coding: UTF-8 -*-
# http://juilin77.blogspot.com/
# v20200419
# Automate The Boring Stuff With Python - Chapter 9

# ========== 9.8.1 ==========
import os
import shutil

oldPath = input('The old folder path: ')
newPath = input('The new folder path: ')

if not os.path.exists(newPath):
    os.mkdir(os.path.abspath(newPath))

for folderName, subFolders, fileNames in os.walk(os.path.abspath(oldPath)):
    for fileName in fileNames:
        if fileName.endswith('.jpg') or fileName.endswith('.pdf'):
            foundFile = fileName
            print('Found: ', foundFile)
            shutil.move(os.path.join(folderName, foundFile), os.path.abspath(newPath))


# ========== 9.8.2 ==========
import os

folderPath = input('The folder path: ')
bigSize = input('The size is ?: ')

for folderName, subFolders, fileNames in os.walk(folderPath):
    for fileName in fileNames:
        if os.path.getsize(os.path.abspath(fileName)) > int(bigSize):
            print(os.path.abspath(fileName))


Reference:
Automate the Boring Stuff with Python
Python編程快速上手--讓繁瑣工作自動化
ISBN-10: B01N6B9BSA
https://www.amazon.com/Python%E7%BC%96%E7%A8%8B%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B-%E8%AE%A9%E7%B9%81%E7%90%90%E5%B7%A5%E4%BD%9C%E8%87%AA%E5%8A%A8%E5%8C%96-%E7%BE%8E-Al-Sweigart%EF%BC%88%E6%96%AF%E7%BB%B4%E5%8A%A0%E7%89%B9%EF%BC%89/dp/B01I0XN8XY/ref=sr_1_1?ie=UTF8&qid=1543814481&sr=8-1&keywords=9787115422699

官網:
https://automatetheboringstuff.com/


最初發表 / 最後更新: 2020.04.20 / 2020.04.20

0 comments:

張貼留言