>>> from env_helper import info; info()
页面更新时间: 2023-06-30 19:18:04
运行环境:
Linux发行版本: Debian GNU/Linux 12 (bookworm)
操作系统内核: Linux-6.1.0-9-amd64-x86_64-with-glibc2.36
Python版本: 3.11.2
3.3. 使用 shutil
模块¶
shutil
(或称为 shell
工具)模块中包含一些函数,让你在Python程序中复制、移动、改名和删除文件。
要使用 shutil
的函数,首先需要 import shutil
。
3.3.1. 复制文件和文件夹¶
shutil
模块提供了一些函数,用于复制文件和整个文件夹。
调用 shutil.copy(source,destination)
, 将路径 source
处的文件复制到路径 destination
处的文件夹( source
和
destination
都是字符串)。 如果 destination
是一个文件名,它将作为被复制文件的新名字。
该函数返回一个字符串,表示被复制文件的路径。
在交互式环境中输入以下代码,看看 shutil.copy()
的效果:
>>> import shutil, os
>>> shutil.copy('./chapter.ipynb','/tmp')
'/tmp/chapter.ipynb'
>>> shutil.copy('./chapter.ipynb','/tmp/new_chapter.ipynb')
'/tmp/new_chapter.ipynb'
第一个 shutil.copy()
调用将文件 复制到文件夹
C::raw-latex:`\delicious`。返回值是刚刚被复制的文件的路径。
请注意,因为指定了一个文件夹作为目的地〇, 原来的文件名 spam.txt
就被用作新复制的文件名。 第二个 shutil.copy()
调用也将文件
C::raw-latex:`\eggs`.txt 复制到文件夹C::raw-latex:`\delicious`,
但为新文件提供了一个名字 eggs2.txt
。
shutil.copy()
将复制一个文件,shutil.copytree()
将复制整个文件夹,以及它包含的文件夹和文件。 调用
shutil.copytree(source,destination)
,将路径 source
处的文件夹, 包括它的所有文件和子文件夹,复制到路径 destination
处的文件夹。 source
和 destination
参数都是字符串。该函数返回一个字符串,是新复制的文件夹的路径。
在交互式环境中输入以下代码:
>>> if os.path.exists('/tmp/dest_backup')==False:
>>> shutil.copytree('./', '/tmp/dest_backup')
shutil.copytree()
调用创建了一个新文件夹, 名为 dest_backup
,其中的内容与原来的 ./
文件夹一样。 现在你已经完成了资料的备份。
3.3.2. 文件和文件夹的移动与改名¶
调用 shutil.move(source, destination)
, 将路径 source
处的文件夹移动到路径 destination
, 并返回新位置的绝对路径的字符串。
如果 destination
指向一个文件夹, source
文件将移动到
destination
中,并保持原来的文件名。
例如,在交互式环境中输入以下代码:
>>> dest_dir = '/tmp/dst'
>>> if os.path.exists(dest_dir):
>>> pass
>>> else:
>>> os.mkdir(dest_dir)
>>>
>>> shutil.move('/tmp/new_chapter.ipynb', '/tmp/dst')
假定在 /tmp
目录中已存在一个名为 dst
的文件夹, 这个
shutil.move()
调用就是说,将目标文件移动到文件夹 /tmp/dst
中。
如果在 /tmp/dst
中原来已经存在一个文件 new_chapter.ipynb
,它就会被覆写。 因为用这种方式很容易不小心覆写文件,所以在使用
move()
时应该注意。
destination路径也可以指定一个文件名。 在下面的例子中,source文件被移动 并改名。
>>> shutil.move('/tmp/dst/new_chapter.ipynb','/tmp/dst/new_chapter_2.ipynb')
'/tmp/dst/new_chapter_2.ipynb'
这一行是说,“将C::raw-latex:`\bacon`.txt移动到文件夹C::raw-latex:`\eggs`, 完成之后,将bacon.txt文件改名为new_bacon.txt 。”
前面两个例子都假设在C::raw-latex:`\目录下有一个文件夹eggs`。
但是如果没有eggs文件夹, move()
就会将 bacon.txt
改名,变成名为
eggs
的文件。
>>> my_fies = Path("chd3_test/hello.txt")
>>> if my_fies.is_file():
>>> shutil.move('/home/shaopp/jubook/chd3_test/hello.txt', '/home/shaopp/jubook/chd3_test/eggs')
这里, move()
在C::raw-latex:`\目录下找不到名为eggs的文件夹`,
所以假定destination指的是一个文件,而非文件夹。 所以 bacon.txt
文本文件被改名为 eggs (没有.txt 文件扩展名的文本文件),
但这可能不是你所希望的!这可能是程序中很难发现的缺陷, 因为move()
调用会很开心地做一些事情, 但和你所期望的完全不同。这也是在使用
move()
时要小心的另一个理由。
最后,构成目的地的文件夹必须己经存在, 否则 Python 会抛出异常。
3.3.3. 永久删除文件和文件夹¶
利用 os
模块中的函数, 可以删除一个文件或一个空文件夹。 但利用
shutil
模块, 可以删除一个文件夹及其所有的内容。
用
os.unlink(path)
将删除path
处的文件。调用
os.rmdir(path)
将删除path
处的文件夹。该文件夹必须为空,其中没有任何文件和文件夹。调用
shutil.rmtree(path)
将删除path
处的文件夹,
它包含的所有文件和文件夹都会被删除。
在程序中使用这些函数时要小心!可以第一次运行程序时,
注释掉这些调用,并且加上 print()
调用,
显示会被删除的文件。这样做是一个好主意。
下面有一个Python程序,本来打算删除具有 .txt
扩展名的文件,但有一处录入错误(用粗体突 出显示),结果导致它删除了.rxt
文件。
>>> import os
>>> os.chdir('/home/shaopp/jubook/chd3_test')
>>> for filename in os.listdir():
>>> if filename.endswith('.txt'):
>>> os.unlink(filename)
如果你有某些重要的文件以.rxt 结尾,它们就会被不小心永久地删除。 作为替代,你应该先运行像这样的程序:
>>> import os
>>> for filename in os.listdir('/home/shaopp/jubook/chd3_test'):
>>> if filename.endswith('.txt'):
>>> #os.unlink(filename)
>>> print(filename)
现在 os.unlink()
调用被注释掉,所以Python会忽略它。
作为替代,你会打印出将被删除的文件名。
先运行这个版本的程序,你就会知道,你不小心告诉程序要删除.rxt文件,
而不是.txt 文件。
在确定程序按照你的意图工作后,删除 print(filename)
代码行, 取消
os.imlink(filename)
代码行的注释。然后再次运行该程序,实际删除这些文件。
3.3.4. 用 send2trash
模块安全地删除¶
因为Python内建的 shutil.rmtree()
函数
不可恢复地删除文件和文件夹,所以用起来可能有危险。
删除文件和文件夹的更好方法, 是使用第三方的 send2trash
模块。
你可以在终端窗口中运行如下命令安装该模块。
sudo apt install -y python3-send2trash
或
pip install send2trash
利用 send2trash
,比Python常规的删除函数要安全得多,
因为它会将文件夹和文件发送到计算机的垃圾箱或回收站,而不是永久删除它们。
如果因程序缺陷而用send2trash
删除了某些你不想删除的东西,稍后可以从垃圾箱恢复。
安装 send2trash
后,在交互式环境中输入以下代码:
>>> import send2trash
>>> baconFile = open('bacon.txt', 'a') #creates the file
>>> baconFile.write('Bacon is not a vegetable.')
25
>>> baconFile.close()
>>> send2trash.send2trash('bacon.txt')
一般来说,总是应该使用 send2trash.send2trash()
函数
来删除文件和文件夹。虽然它将文件发送到垃圾箱,
让你稍后能够恢复它们,但是这不像永久删除文件,
不会释放磁盘空间。如果你希望程序释放磁盘空间, 就要用 os
和
shutil
来删除文件和文件夹。 请注意, send2trash()
函数只能将文件送到垃圾箱, 不能从中恢复文件。