乐趣区

关于python:教你怎么用python操作文件

Python 中有几个内置模块和办法来解决文件。这些办法被宰割到例如 os, os.path , shutil 和 pathlib 等等几个模块中。文章将列举 Python 中对文件最罕用的操作和办法。
在这篇文章中,你将学习如何:

  • 获取文件属性
  • 创立目录
  • 文件名模式匹配
  • 遍历目录树
  • 创立临时文件和目录
  • 删除文件和目录
  • 复制、挪动和重命名文件和目录
  • 创立和解压 ZIP 和 TAR 档案
  • 应用 fileinput 模块关上多个文件

Python 中文件数据的读和写
应用 Python 对文件进行读和写是非常简略的。为此,你首先必须应用适合的模式关上文件。这里有一个如何关上文本文件并读取其内容的例子。

with open('data.txt', 'r') as f:
    data = f.read()
    print('context: {}'.format(data))

open() 接管一个文件名和一个模式作为它的参数,r 示意以只读模式关上文件。想要往文件中写数据的话,则用 w 作为参数。

with open('data.txt', 'w') as f:
    data = 'some data to be written to the file'
    f.write(data)

在上述例子中,open()关上用于读取或写入的文件并返回文件句柄(本例子中的 f),该句柄提供了可用于读取或写入文件数据的办法。浏览 Working With File I/O in Python 获取更多对于如何读写文件的信息。

获取目录列表
假如你以后的工作目录有一个叫 my_directory 的子目录,该目录蕴含如下内容:

.
├── file1.py
├── file2.csv
├── file3.txt
├── sub_dir
│   ├── bar.py
│   └── foo.py
├── sub_dir_b
│   └── file4.txt
└── sub_dir_c
    ├── config.py
    └── file5.txt

Python 内置的 os 模块有很多有用的办法能被用来列出目录内容和过滤后果。为了获取文件系统中特定目录的所有文件和文件夹列表,能够在遗留版本的 Python 中应用 os.listdir() 或 在 Python 3.x 中应用 os.scandir()。如果你还想获取文件和目录属性 (如文件大小和批改日期),那么 os.scandir() 则是首选的办法。
应用遗留版本的 Python 获取目录列表

import os
entries = os.listdir('my_directory')

os.listdir() 返回一个 Python 列表,其中蕴含 path 参数所指目录的文件和子目录的名称。

['file1.py', 'file2.csv', 'file3.txt', 'sub_dir', 'sub_dir_b', 'sub_dir_c']

目录列表当初看上去不容易浏览,对 os.listdir() 的调用后果应用循环打印有助于查看。

for entry in entries:
    print(entry)

"""
file1.py
file2.csv
file3.txt
sub_dir
sub_dir_b
sub_dir_c
"""

应用古代版本的 Python 获取目录列表
在古代 Python 版本中,能够应用 os.scandir() 和 pathlib.Path 来代替 os.listdir()。

os.scandir() 在 Python 3.5 中被援用,其文档为 PEP 471。os.scandir() 调用时返回一个迭代器而不是一个列表。import os
entries = os.scandir('my_directory')
print(entries)
# <posix.ScandirIterator at 0x105b4d4b0>

ScandirIterator 指向了当前目录中的所有条目。你能够遍历迭代器的内容,并打印文件名。

import os
with os.scandir('my_directory') as entries:
    for entry in entries:
        print(entry.name)

这里 os.scandir() 和 with 语句一起应用,因为它反对上下文治理协定。应用上下文管理器敞开迭代器并在迭代器耗尽后主动开释获取的资源。在 my_directory 打印文件名的后果就和在 os.listdir() 例子中看到的一样:

file1.py
file2.csv
file3.txt
sub_dir
sub_dir_b
sub_dir_c

另一个获取目录列表的办法是应用 pathlib 模块:

from pathlib import Path

entries = Path('my_directory')
for entry in entries.iterdir():
    print(entry.name)

pathlib.Path() 返回的是 PosixPath 或 WindowsPath 对象,这取决于操作系统。
pathlib.Path() 对象有一个 .iterdir() 的办法用于创立一个迭代器蕴含该目录下所有文件和目录。由 .iterdir() 生成的每个条目都蕴含文件或目录的信息,例如其名称和文件属性。pathlib 在 Python3.4 时被第一次引入,并且是对 Python 一个很好的增强,它为文件系统提供了面向对象的接口。

在下面的例子中,你调用 pathlib.Path() 并传入了一个门路参数。而后调用 .iterdir() 来获取 my_directory 下的所有文件和目录列表。

pathlib 提供了一组类,以简略并且面向对象的形式提供了门路上的大多数常见的操作。应用 pathlib 比起应用 os 中的函数更加无效。和 os 相比,应用 pathlib 的另一个益处是缩小了操作文件系统门路所导入包或模块的数量。想要理解更多信息,能够浏览 Python 3’s pathlib Module: Taming the File System。

运行上述代码会失去如下后果:

file1.py
file2.csv
file3.txt
sub_dir
sub_dir_b
sub_dir_c

应用 pathlib.Path() 或 os.scandir() 来代替 os.listdir() 是获取目录列表的首选办法,尤其是当你须要获取文件类型和文件属性信息的时候。

pathlib.Path() 提供了在 os 和 shutil 中大部分解决文件和门路的性能,并且它的办法比这些模块更加无效。咱们将探讨如何疾速的获取文件属性。

这些函数返回目录中所有内容的列表,包含子目录。这可能并总是你始终想要的后果,下一节将向你展现如何从目录列表中过滤后果。

列出目录中的所有文件

这节将向你展现如何应用 os.listdir(),os.scandir() 和 pathlib.Path() 打印出目录中文件的名称。为了过滤目录并仅列出 os.listdir() 生成的目录列表的文件,要应用 os.path:

import os

basepath = 'my_directory'
for entry in os.listdir(basepath):
    # 应用 os.path.isfile 判断该门路是否是文件类型
    if os.path.isfile(os.path.join(base_path, entry)):
        print(entry)

在这里调用 os.listdir() 返回指定门路中所有内容的列表,接着应用 os.path.isfile() 过滤列表让其只显示文件类型而非目录类型。代码执行后果如下:

file1.py
file2.csv
file3.txt

一个更简略的形式来列出一个目录中所有的文件是应用 os.scandir() 或 pathlib.Path() :

import os

basepath = 'my_directory'
with os.scandir(basepath) as entries:
    for entry in entries:
        if entry.is_file():
            print(entry.name)

应用 os.scandir() 比起 os.listdir() 看上去更分明和更容易了解。对 ScandirIterator 的每一项调用 entry.isfile(),如果返回 True 则示意这一项是一个文件。上述代码的输入如下:

file1.py
file3.txt
file2.csv

接着,展现如何应用 pathlib.Path() 列出一个目录中的文件:

from pathlib import Path

basepath = Path('my_directory')
for entry in basepath.iterdir():
    if entry.is_file():
        print(entry.name)

在 .iterdir() 产生的每一项调用 .is_file()。产生的输入后果和下面雷同:

file1.py
file3.txt
file2.csv

如果将 for 循环和 if 语句组合成单个生成器表达式,则上述的代码能够更加简洁。对于生成器表达式,举荐一篇 Dan Bader 的文章。
批改后的版本如下:

from pathlib import Path

basepath = Path('my_directory')
files_in_basepath = (entry for entry in basepath.iterdir() if entry.is_file())
for item in files_in_basepath:
    print(item.name)

上述代码的执行后果和之前雷同。本节展现应用 os.scandir() 和 pathlib.Path() 过滤文件或目录比应用 os.listdir() 和 os.path 更直观,代码看起来更简洁。
列出子目录
如果要列出子目录而不是文件,请应用上面的办法。当初展现如何应用 os.listdir() 和 os.path() :

import os

basepath = 'my_directory'
for entry in os.listdir(basepath):
    if os.path.isdir(os.path.join(basepath, entry)):
        print(entry)

当你屡次调用 os.path,join() 时,以这种形式操作文件系统就会变得很轻便。在我电脑上运行此代码会产生以下输入:

sub_dir
sub_dir_b
sub_dir_c

上面是如何应用 os.scandir():

import os

basepath = 'my_directory'
with os.scandir(basepath) as entries:
    for entry in entries:
        if entry.is_dir():
            print(entry.name)

与文件列表中的示例一样,此处在 os.scandir() 返回的每一项上调用 .is_dir()。如果这项是目录,则 is_dir() 返回 True,并打印出目录的名称。输入后果和下面雷同:

sub_dir_c
sub_dir_b
sub_dir

上面是如何应用 pathlib.Path():

from pathlib import Path

basepath = Path('my_directory')
for entry in basepath.iterdir():
    if entry.is_dir():
        print(entry.name)

在 .iterdir() 迭代器返回的每一项上调用 is_dir() 查看是文件还是目录。如果该项是目录,则打印其名称,并且生成的输入与上一示例中的输入雷同:

sub_dir_c
sub_dir_b
sub_dir

获取文件属性
Python 能够很轻松的获取文件大小和批改工夫等文件属性。能够通过应用 os.stat(),os.scandir() 或 pathlib.Path 来获取。

os.scandir() 和 pathlib.Path() 能间接获取到蕴含文件属性的目录列表。这可能比应用 os.listdir() 列出文件而后获取每个文件的文件属性信息更加无效。

上面的例子显示了如何获取 my_directory 中文件的最初批改工夫。以工夫戳的形式输入:

import os

with os.scandir('my_directory') as entries:
    for entry in entries:
        info = entry.stat()
        print(info.st_mtime)
        
"""
1548163662.3952665
1548163689.1982062
1548163697.9175904
1548163721.1841028
1548163740.765162
1548163769.4702623
"""

os.scandir() 返回一个 ScandirIterator 对象。ScandirIterator 对象中的每一项有 .stat() 办法能获取对于它指向文件或目录的信息。.stat() 提供了例如文件大小和最初批改工夫的信息。在下面的示例中,代码打印了 st_time 属性,该属性是上次批改文件内容的工夫。
pathlib 模块具备相应的办法,用于获取雷同后果的文件信息:

from pathlib import Path

basepath = Path('my_directory')
for entry in basepath.iterdir():
    info = entry.stat()
    print(info.st_mtime)

"""
1548163662.3952665
1548163689.1982062
1548163697.9175904
1548163721.1841028
1548163740.765162
1548163769.4702623
"""

在下面的例子中,循环 .iterdir() 返回的迭代器并通过对其中每一项调用 .stat() 来获取文件属性。st_mtime 属性是一个浮点类型的值,示意的是工夫戳。为了让 st_time 返回的值更容易浏览,你能够编写一个辅助函数将其转换为一个 datetime 对象:

import datetime                                                                   
from pathlib import Path                                                          
                                                                                  
                                                                                  
def timestamp2datetime(timestamp, convert_to_local=True, utc=8, is_remove_ms=True)
    """                                                                           
    转换 UNIX 工夫戳为 datetime 对象                                                       
    :param timestamp: 工夫戳                                                         
    :param convert_to_local: 是否转为本地工夫                                             
    :param utc: 时区信息,中国为 utc+8                                                     
    :param is_remove_ms: 是否去除毫秒                                                   
    :return: datetime 对象                                                          
    """                                                                           
    if is_remove_ms:                                                              
        timestamp = int(timestamp)                                                
    dt = datetime.datetime.utcfromtimestamp(timestamp)                            
    if convert_to_local:                                                          
        dt = dt + datetime.timedelta(hours=utc)                                   
    return dt                                                                     
                                                                                  
                                                                                  
def convert_date(timestamp, format='%Y-%m-%d %H:%M:%S'):                          
    dt = timestamp2datetime(timestamp)                                            
    return dt.strftime(format)                                                    
                                                                                  
                                                                                  
basepath = Path('my_directory')                                                   
for entry in basepath.iterdir():
    if entry.is_file()
        info = entry.stat()                                                           
        print('{} 上次批改工夫为 {}'.format(entry.name, timestamp2datetime(info.st_mtime)))  

首先失去 my_directory 中文件的列表以及它们的属性,而后调用 convert_date() 来转换文件最初批改工夫让其以一种人类可读的形式显示。convert_date() 应用 .strftime() 将 datetime 类型转换为字符串。
上述代码的输入后果:

file3.txt 上次批改工夫为 2019-01-24 09:04:39
file2.csv 上次批改工夫为 2019-01-24 09:04:39
file1.py 上次批改工夫为 2019-01-24 09:04:39

将日期和工夫转换为字符串的语法可能会让你感到凌乱。如果要理解更多的信息,请查问相干的官网文档。另一个形式则是浏览 strftime.org。

创立目录
你编写的程序迟早须要创立目录以便在其中存储数据。os 和 pathlib 蕴含了创立目录的函数。咱们将会思考如下办法:

创立单个目录
要创立单个目录,把目录门路作为参数传给 os.mkdir() :

import os

os.mkdir('example_directory')

如果该目录曾经存在,os.mkdir() 将抛出 FileExistsError 异样。或者,你也能够应用 pathlib 来创立目录:

from pathlib import Path

p = Path('example_directory')
p.mkdir()

如果门路曾经存在,mkdir() 会抛出 FileExistsError 异样:

FileExistsError: [Errno 17] File exists: 'example_directory'

为了防止像这样的谬误抛出,当产生谬误时捕捉谬误并让你的用户晓得:

from pathlib import Path

p = Path('example_directory')
try:
    p.mkdir()
except FileExistsError as e:
    print(e)

或者,你能够给 .mkdir() 传入 exist_ok=True 参数来疏忽 FileExistsError 异样:

from pathlib import Path

p = Path('example_directory')
p.mkdir(exist_ok=True)

如果目录已存在,则不会引起谬误。
创立多个目录
os.makedirs() 和 os.mkdir() 相似。两者之间的区别在于,os.makedirs() 不仅能够创立独自的目录,还能够递归的创立目录树。换句话说,它能够创立任何必要的两头文件夹,来确保存在残缺的门路。

os.makedirs() 和在 bash 中运行 mkdir -p 相似。例如,要创立一组目录像 2018/10/05,你能够像上面那样操作:

import os

os.makedirs('2018/10/05', mode=0o770)

上述代码创立了 2018/10/05 的目录构造并为所有者和组用户提供读、写和执行权限。默认的模式为 0o777,减少了其余用户组的权限。无关文件权限以及模式的利用形式的更多详细信息,请参考 文档。
运行 tree 命令确认咱们利用的权限:

$ tree -p -i .
.
[drwxrwx---]  2018
[drwxrwx---]  10
[drwxrwx---]  05

上述代码打印出当前目录的目录树。tree 通常被用来以树形构造列出目录的内容。传入 -p 和 -i 参数则会以垂直列表打印出目录名称以及其文件权限信息。-p 用于输入文件权限,-i 则用于让 tree 命令产生一个没有缩进线的垂直列表。
正如你所看到的,所有的目录都领有 770 权限。另一个形式创立多个目录是应用 pathlib.Path 的 .mkdir() :

from pathlib import Path

p = Path('2018/10/05')
p.mkdir(parents=True, exist_ok=True)

通过给 Path.mkdir() 传递 parents=True 关键字参数使它创立 05 目录和使其门路无效的所有父级目录。
在默认状况下,os.makedirs() 和 pathlib.Path.mkdir() 会在目标目录存在的时候抛出 OSError。通过每次调用函数时传递 exist_ok=True 作为关键字参数则能够笼罩此行为(从 Python3.2 开始)。
运行上述代码会失去像上面的构造:

└── 2018
    └── 10
        └── 05

我更喜爱在创立目录时应用 pathlib,因为我能够应用雷同的函数办法来创立一个或多个目录。

文件名模式匹配
应用上述办法之一获取目录中的文件列表后,你可能心愿搜寻和特定的模式匹配的文件。
上面这些是你能够应用的办法和函数:

  • endswith() 和 startswith() 字符串办法
  • fnmatch.fnmatch()
  • glob.glob()
  • pathlib.Path.glob()

这些办法和函数是上面要探讨的。本大节的示例将在名为 some_directory 的目录下执行,该目录具备以下的构造:

.
├── admin.py
├── data_01_backup.txt
├── data_01.txt
├── data_02_backup.txt
├── data_02.txt
├── data_03_backup.txt
├── data_03.txt
├── sub_dir
│   ├── file1.py
│   └── file2.py
└── tests.py

如果你正在应用 Bash shell,你能够应用以下的命令创立上述目录构造:

mkdir some_directory
cd some_directory
mkdir sub_dir
touch sub_dir/file1.py sub_dir/file2.py
touch data_{01..03}.txt data_{01..03}_backup.txt admin.py tests.py

这将会创立 some_directory 目录并进入它,接着创立 sub_dir。下一行在 sub_dir 创立 file1.py 和 file2.py,最初一行应用扩大创立其它所有文件。想要学习更多对于 shell 扩大,请浏览 这里。
应用字符串办法
Python 有几个内置 批改和操作字符串 的办法。当在匹配文件名时,其中的两个办法 .startswith() 和 .endswith() 十分有用。要做到这点,首先要获取一个目录列表,而后遍历。

import os

for f_name in os.listdir('some_directory'):
    if f_name.endswith('.txt'):
        print(f_name)

上述代码找到 some_directory 中的所有文件,遍历并应用 .endswith() 来打印所有扩大名为 .txt 的文件名。运行代码在我的电脑上输入如下:

data_01.txt
data_01_backup.txt
data_02.txt
data_02_backup.txt
data_03.txt
data_03_backup.txt

应用 fnmatch 进行简略文件名模式匹配
字符串办法匹配的能力是无限的。fnmatch 有对于模式匹配有更先进的函数和办法。咱们将思考应用 fnmatch.fnmatch(),这是一个反对应用 * 和 ? 等通配符的函数。例如,应用 fnmatch 查找目录中所有 .txt 文件,你能够这样做:

import os
import fnmatch

for f_name in os.listdir('some_directory'):
    if fnmatch.fnmatch(f_name, '*.txt'):
        print(f_name)

迭代 some_directory 中的文件列表,并应用 .fnmatch() 对扩大名为 .txt 的文件执行通配符搜寻。
更先进的模式匹配
假如你想要查找合乎特定掉件的 .txt 文件。例如,你可能指向找到蕴含单次 data 的 .txt 文件,一组下划线之间的数字,以及文件名中蕴含单词 backup。就相似于 data_01_backup, data_02_backup, 或 data_03_backup。
你能够这样应用 fnmatch.fnmatch() :

import os
import fnmatch

for f_name in os.listdir('some_directory'):
    if fnmatch.fnmatch(f_name, 'data_*_backup.txt'):
        print(f_name)

这里就仅仅打印出匹配 data__backup.txt 模式的文件名称。模式中的 将匹配任何字符,因而运行这段代码则将查找文件名以 data 结尾并以 backup.txt 的所有文本文件,就行上面的输入所示 :

data_01_backup.txt
data_02_backup.txt
data_03_backup.txt

应用 glob 进行文件名模式匹配
另一个有用的模式匹配模块是 glob。

.glob() 在 glob 模块中的左右就像 fnmatch.fnmatch(),然而与 fnmach.fnmatch() 不同的是,它将以 . 结尾的文件视为非凡文件。
UNIX 和相干零碎在文件列表中应用通配符像 ? 和 * 示意全匹配。

例如,在 UNIX shell 中应用 mv .py python_files 挪动所有 .py 扩展名 的文件从当前目录到 python_files。这 是一个通配符示意任意数量的字符,*.py 是一个全模式。Windows 操作系统中不提供此 shell 性能。但 glob 模块在 Python 中增加了此性能,使得 Windows 程序能够应用这个个性。

这里有一个应用 glob 模块在当前目录下查问所有 Python 代码文件:

import glob

print(glob.glob('*.py'))

glob.glob(‘*.py’) 搜寻当前目录中具备 .py 扩展名的文件,并且将它们以列表的模式返回。glob 还反对 shell 款式的通配符来进行匹配 :

import glob

for name in glob.glob('*[0-9]*.txt'):
    print(name)

这将找到所有文件名中蕴含数字的文本文件(.txt) :

data_01.txt
data_01_backup.txt
data_02.txt
data_02_backup.txt
data_03.txt
data_03_backup.txt

glob 也很容易在子目录中递归的搜寻文件:

import glob

for name in glob.iglob('**/*.py', recursive=True):
    print(name)

这里例子应用了 glob.iglob() 在当前目录和子目录中搜寻所有的 .py 文件。传递 recursive=True 作为 .iglob() 的参数使其搜寻当前目录和子目录中的 .py 文件。glob.glob() 和 glob.iglob() 不同之处在于,iglob() 返回一个迭代器而不是一个列表。
运行上述代码会失去以下后果:

admin.py
tests.py
sub_dir/file1.py
sub_dir/file2.py

pathlib 也蕴含相似的办法来灵便的获取文件列表。上面的例子展现了你能够应用 .Path.glob() 列出以字母 p 开始的文件类型的文件列表。

from pathlib import Path

p = Path('.')

for name in p.glob('*.p*'):
    print(name)

调用 p.glob(‘.p‘) 会返回一个指向当前目录中所有扩展名以字母 p 结尾的文件的生成器对象。
Path.glob() 和下面探讨过的 os.glob() 相似。正如你看到的,pathlib 混合了许多 os,os.path 和 glob 模块的最佳个性到一个模块中,这使得应用起来很不便。
回顾一下,这是咱们在本节中介绍的功能表:

遍历目录和解决文件
一个常见的编程工作是遍历目录树并解决目录树中的文件。让咱们来探讨一下如何应用内置的 Python 函数 os.walk() 来实现这一性能。os.walk() 用于通过从上到下或从下到上遍历树来生成目录树中的文件名。处于本节的目标,咱们想操作以下的目录树:

├── folder_1
│   ├── file1.py
│   ├── file2.py
│   └── file3.py
├── folder_2
│   ├── file4.py
│   ├── file5.py
│   └── file6.py
├── test1.txt
└── test2.txt

以下是一个示例,演示如何应用 os.walk() 列出目录树中的所有文件和目录。
os.walk() 默认是从上到下遍历目录:

import os
for dirpath, dirname, files in os.walk('.'):
   print(f'Found directory: {dirpath}')
   for file_name in files:
       print(file_name)

os.walk() 在每个循环中返回三个值:

  • 以后文件夹的名称
  • 以后文件夹中子文件夹的列表
  • 以后文件夹中文件的列表

在每次迭代中,会打印出它找到的子目录和文件的名称:

Found directory: .
test1.txt
test2.txt
Found directory: ./folder_1
file1.py
file3.py
file2.py
Found directory: ./folder_2
file4.py
file5.py
file6.py

要以自下而上的形式遍历目录树,则将 topdown=False 关键字参数传递给 os.walk():

for dirpath, dirnames, files in os.walk('.', topdown=False):
    print(f'Found directory: {dirpath}')
    for file_name in files:
        print(file_name)

传递 topdown=False 参数将使 os.walk() 首先打印出它在子目录中找到的文件:

Found directory: ./folder_1
file1.py
file3.py
file2.py
Found directory: ./folder_2
file4.py
file5.py
file6.py
Found directory: .
test1.txt
test2.txt

如你看见的,程序在列出根目录的内容之前列出子目录的内容。这在在你想要递归删除文件和目录的状况下十分有用。你将在以下局部中学习如何执行此操作。默认状况下,os.walk 不会拜访通过软连贯创立的目录。能够通过应用 followlinks = True 参数来笼罩默认行为。

创立临时文件和目录
Python 提供了 tempfile 模块来便捷的创立临时文件和目录。
tempfile 能够在你程序运行时关上并存储长期的数据在文件或目录中。tempfile 会在你程序进行运行后删除这些临时文件。
当初,让咱们看看如何创立一个临时文件:

from tempfile import  TemporaryFile

# 创立一个临时文件并为其写入一些数据
fp = TemporaryFile('w+t')
fp.write('Hello World!')
# 回到开始,从文件中读取数据
fp.seek(0)
data = fp.read()
print(data)
# 敞开文件,之后他将会被删除
fp.close()

第一步是从 tempfile 模块导入 TemporaryFile。接下来,应用 TemporaryFile() 办法并传入一个你想关上这个文件的模式来创立一个相似于对象的文件。这将创立并关上一个可用作长期存储区域的文件。

在下面的示例中,模式为 w + t,这使得 tempfile 在写入模式下创立长期文本文件。没有必要为临时文件提供文件名,因为在脚本运行结束后它将被销毁。
写入文件后,您能够从中读取并在实现解决后将其敞开。一旦文件敞开后,将从文件系统中删除。如果须要命名应用 tempfile 生成的临时文件,请应用 tempfile.NamedTemporaryFile()。

应用 tempfile 创立的临时文件和目录存储在用于存储临时文件的非凡系统目录中。Python 将在目录列表搜寻用户能够在其中创立文件的目录。

在 Windows 上,目录按程序为 C:\TEMP,C:\TMP,\TEMP 和 \TMP。在所有其余平台上,目录按程序为 / tmp,/var/tmp 和 /usr/tmp。如果上述目录中都没有,tempfile 将在当前目录中存储临时文件和目录。

.TemporaryFile() 也是一个上下文管理器,因而它能够与 with 语句一起应用。应用上下文管理器会在读取文件后主动敞开和删除文件:

with TemporaryFile('w+t') as fp:
    fp.write('Hello universe!')
    fp.seek(0)
    fp.read()
# 临时文件当初曾经被敞开和删除

这将创立一个临时文件并从中读取数据。一旦读取文件的内容,就会敞开临时文件并从文件系统中删除。
tempfile 也可用于创立长期目录。让咱们看一下如何应用 tempfile.TemporaryDirectory()来做到这一点:

import tempfile
import os

tmp = ''
with tempfile.TemporaryDirectory() as tmpdir:
    print('Created temporary directory', tmpdir)
    tmp = tmpdir
    print(os.path.exists(tmpdir))

print(tmp)
print(os.path.exists(tmp))

调用 tempfile.TemporaryDirectory() 会在文件系统中创立一个长期目录,并返回一个示意该目录的对象。在下面的示例中,应用上下文管理器创立目录,目录的名称存储在 tmpdir 变量中。第三行打印出长期目录的名称,os.path.exists(tmpdir) 来确认目录是否理论在文件系统中创立。
在上下文管理器退出上下文后,长期目录将被删除,并且对 os.path.exists(tmpdir)的调用将返回 False,这意味着该目录已胜利删除。

删除文件和目录
您能够应用 os,shutil 和 pathlib 模块中的办法删除单个文件,目录和整个目录树。以下将介绍如何删除你不再须要的文件和目录。
Python 中删除文件
要删除单个文件,请应用 pathlib.Path.unlink(),os.remove() 或 os.unlink()。
os.remove() 和 os.unlink() 在语义上是雷同的。要应用 os.remove()删除文件,请执行以下操作:

import os

data_file = 'C:\\Users\\vuyisile\\Desktop\\Test\\data.txt'
os.remove(data_file)

应用 os.unlink() 删除文件与应用 os.remove() 的形式相似:

import os

data_file = 'C:\\Users\\vuyisile\\Desktop\\Test\\data.txt'
os.unlink(data_file)

在文件上调用 .unlink() 或 .remove() 会从文件系统中删除该文件。如果传递给它们的门路指向目录而不是文件,这两个函数将抛出 OSError。为防止这种状况,能够查看你要删除的内容是否是文件,并在确认是文件时执行删除操作,或者能够应用异样解决来解决 OSError:

import os

data_file = 'home/data.txt'
# 如果类型是文件则进行删除
if os.path.is_file(data_file):
    os.remove(data_file)
else:
    print(f'Error: {data_file} not a valid filename')

os.path.is_file() 查看 data_file 是否实际上是一个文件。如果是,则通过调用 os.remove() 删除它。如果 data_file 指向文件夹,则会向控制台输入谬误音讯。
以下示例阐明如何在删除文件时应用异样解决来处理错误:

import os

data_file = 'home/data.txt'
# 应用异样解决
try:
    os.remove(data_file)
except OSError as e:
    print(f'Error: {data_file} : {e.strerror}')

下面的代码尝试在查看其类型之前先删除该文件。如果 data_file 实际上不是文件,则抛出的 OSError 将在 except 子句中解决,并向控制台输入谬误音讯。打印出的谬误音讯应用 Python f-strings 格式化。
最初,你还能够应用 pathlib.Path.unlink() 删除文件:

from pathlib import Path

data_file = Path('home/data.txt')
try:
    data_file.unlink()
except IsADirectoryError as e:
    print(f'Error: {data_file} : {e.strerror}')

这将创立一个名为 data_file 的 Path 对象,该对象指向一个文件。在 data_file 上调用.unlink()将删除 home / data.txt。如果 data_file 指向目录,则引发 IsADirectoryError。值得注意的是,下面的 Python 程序和运行它的用户具备雷同的权限。如果用户没有删除文件的权限,则会引发 PermissionError。
删除目录
规范库提供了一下函数来删除目录:

os.rmdir()
pathlib.Path.rmdir()
shutil.rmtree()

要删除单个目录或文件夹能够应用 os.rmdir() 或 pathlib.Path.rmdir()。这两个函数只在你删除空目录的时候无效。如果目录不为空,则会抛出 OSError。上面演示如何删除一个文件夹:

import os

trash_dir = 'my_documents/bad_dir'

try:
    os.rmdir(trash_dir)
except OSError as e:
    print(f'Error: {trash_dir} : {e.strerror}')

当初,trash_dir 曾经通过 os.rmdir() 被删除了。如果目录不为空,则会在屏幕上打印错误信息:

Traceback (most recent call last):
  File '<stdin>', line 1, in <module>
OSError: [Errno 39] Directory not empty: 'my_documents/bad_dir'

同样,你也可应用 pathlib 来删除目录:

from pathlib import Path

trash_dir = Path('my_documents/bad_dir')

try:
    trash_dir.rmdir()
except OSError as e:
    print(f'Error: {trash_dir} : {e.strerror}')

这里创立了一个 Path 对象指向要被删除的目录。如果目录为空,调用 Path 对象的 .rmdir() 办法删除它。
删除残缺的目录树
要删除非空目录和残缺的目录树,Python 提供了 shutil.rmtree() :

import shutil

trash_dir = 'my_documents/bad_dir'

try:
    shutil.rmtree(trash_dir)
except OSError as e:
    print(f'Error: {trash_dir} : {e.strerror}')

当调用 shutil.rmtree() 时,trash_dir 中的所有内容都将被删除。在某些状况下,你可能心愿以递归形式删除空文件夹。你能够应用下面探讨的办法之一联合 os.walk() 来实现此操作:

import os

for dirpath, dirnames, files in os.walk('.', topdown=False):
    try:
        os.rmdir(dirpath)
    except OSError as ex:
        pass

这将遍历目录树并尝试删除它找到的每个目录。如果目录不为空,则引发 OSError 并跳过该目录。下表列出了本节中波及的性能:

复制、挪动和重命名文件和目录
Python 附带了 shutil 模块。shutil 是 shell 实用程序的缩写。它为文件提供了许多高级操作,来反对文件和目录的复制,归档和删除。在本节中,你将学习如何挪动和复制文件和目录。
复制文件
shutil 提供了一些复制文件的函数。最罕用的函数是 shutil.copy() 和 shutil.copy2()。应用 shutil.copy() 将文件从一个地位复制到另一个地位,请执行以下操作:

import shutil

src = 'path/to/file.txt'
dst = 'path/to/dest_dir'
shutil.copy(src, dst)

shutil.copy() 与基于 UNIX 的零碎中的 cp 命令相当。shutil.copy(src,dst) 会将文件 src 复制到 dst 中指定的地位。如果 dst 是文件,则该文件的内容将替换为 src 的内容。如果 dst 是目录,则 src 将被复制到该目录中。shutil.copy() 仅复制文件的内容和文件的权限。其余元数据(如文件的创立和批改工夫)不会保留。
要在复制时保留所有文件元数据,请应用 shutil.copy2():

import shutil

src = 'path/to/file.txt'
dst = 'path/to/dest_dir'
shutil.copy2(src, dst)

应用 .copy2() 保留无关文件的详细信息,例如上次访问工夫,权限位,上次批改工夫和标记。
复制目录
尽管 shutil.copy() 只复制单个文件,但 shutil.copytree() 将复制整个目录及其中蕴含的所有内容。shutil.copytree(src,dest) 接管两个参数:源目录和将文件和文件夹复制到的目标目录。
以下是如何将一个文件夹的内容复制到其余地位的示例:

import shutil
dst = shutil.copytree('data_1', 'data1_backup')
print(dst)  # data1_backup

在此示例中,.copytree() 将 data_1 的内容复制到新地位 data1_backup 并返回目标目录。目标目录不能是已存在的。它将被创立而不带有其父目录。shutil.copytree() 是备份文件的一个好办法。
挪动文件和目录
要将文件或目录挪动到其余地位,请应用 shutil.move(src,dst)。
src 是要挪动的文件或目录,dst 是指标:

import shutil
dst = shutil.move('dir_1/', 'backup/')
print(dst)  # 'backup'

如果 backup/ 存在,则 shutil.move(‘dir_1/’,’backup/’) 将 dir_1/ 挪动到 backup/。如果 backup/ 不存在,则 dir_1/ 将重命名为 backup。
重命名文件和目录
Python 蕴含用于重命名文件和目录的 os.rename(src,dst):

import os
os.rename('first.zip', 'first_01.zip')

下面的即将 first.zip 重命名为 first_01.zip。如果指标门路指向目录,则会抛出 OSError。
重命名文件或目录的另一种办法是应用 pathlib 模块中的 rename():

from pathlib import Path
data_file = Path('data_01.txt')
data_file.rename('data.txt')

要应用 pathlib 重命名文件,首先要创立一个 pathlib.Path() 对象,该对象蕴含要替换的文件的门路。下一步是在门路对象上调用 rename() 并传入你要重命名的文件或目录的新名称。

归档
归档是将多个文件打包成一个文件的便捷形式。两种最常见的存档类型是 ZIP 和 TAR。你编写的 Python 程序能够创立存档文件,读取存档文件和从存档文件中提取数据。你将在本节中学习如何读取和写入两种压缩格局。
读取 ZIP 文件
zipfile 模块是一个底层模块,是 Python 规范库的一部分。zipfile 具备能够轻松关上和提取 ZIP 文件的函数。要读取 ZIP 文件的内容,首先要做的是创立一个 ZipFile 对象。ZipFile 对象相似于应用 open() 创立的文件对象。ZipFile 也是一个上下文管理器,因而反对 with 语句:

import zipfile

with zipfile.ZipFile('data.zip', 'r') as zipobj:
    pass

这里创立一个 ZipFile 对象,传入 ZIP 文件的名称并以读取模式下关上。关上 ZIP 文件后,能够通过 zipfile 模块提供的函数拜访无关存档文件的信息。下面示例中的 data.zip 存档是从名为 data 的目录创立的,该目录蕴含总共 5 个文件和 1 个子目录:

.
|
├── sub_dir/
|   ├── bar.py
|   └── foo.py
|
├── file1.py
├── file2.py
└── file3.py

要获取存档文件中的文件列表,请在 ZipFile 对象上调用 namelist():
import zipfile

with zipfile.ZipFile(‘data.zip’, ‘r’) as zipobj:

    zipobj.namelist()

这会生成一个文件列表:

['file1.py', 'file2.py', 'file3.py', 'sub_dir/', 'sub_dir/bar.py', 'sub_dir/foo.py']

.namelist() 返回存档文件中文件和目录的名称列表。要检索无关存档文件中文件的信息,应用 .getinfo():

import zipfile

with zipfile.ZipFile('data.zip', 'r') as zipobj:
    bar_info = zipobj.getinfo('sub_dir/bar.py')
    print(bar_info.file_size)

这将输入:

15277

.getinfo() 返回一个 ZipInfo 对象,该对象存储无关存档文件的单个成员的信息。要获取无关存档文件中文件的信息,请将其门路作为参数传递给 .getinfo()。应用 getinfo(),你能够检索无关存档文件成员的信息,例如上次批改文件的日期,压缩大小及其残缺文件名。拜访 .file_size 将以字节为单位检索文件的原始大小。

以下示例阐明如何在 Python REPL 中检索无关已归档文件的更多详细信息。假如已导入 zipfile 模块,bar_info 与在后面的示例中创立的对象雷同:

>>> bar_info.date_time
(2018, 10, 7, 23, 30, 10)
>>> bar_info.compress_size
2856
>>> bar_info.filename
'sub_dir/bar.py'

bar_info 蕴含无关 bar.py 的详细信息,例如压缩的大小及其残缺门路。
第一行显示了如何检索文件的上次批改日期。下一行显示了如何在归档后获取文件的大小。最初一行显示了存档文件中 bar.py 的残缺门路。

ZipFile 反对上下文管理器协定,这就是你能够将它与 with 语句一起应用的起因。操作实现后会主动敞开 ZipFile 对象。尝试从已敞开的 ZipFile 对象中关上或提取文件将导致谬误。

提取 ZIP 文件
zipfile 模块容许你通过 .extract() 和 .extractall() 从 ZIP 文件中提取一个或多个文件。

默认状况下,这些办法将文件提取到当前目录。它们都采纳可选的门路参数,容许指定要将文件提取到的其余指定目录。如果该目录不存在,则会主动创立该目录。要从压缩文件中提取文件,请执行以下操作:

>>> import zipfile
>>> import os

>>> os.listdir('.')
['data.zip']

>>> data_zip = zipfile.ZipFile('data.zip', 'r')

>>> # 提取单个文件到当前目录
>>> data_zip.extract('file1.py')
'/home/test/dir1/zip_extract/file1.py'

>>> os.listdir('.')
['file1.py', 'data.zip']

>>> # 提所有文件到指定目录
>>> data_zip.extractall(path='extract_dir/')

>>> os.listdir('.')
['file1.py', 'extract_dir', 'data.zip']

>>> os.listdir('extract_dir')
['file1.py', 'file3.py', 'file2.py', 'sub_dir']

>>> data_zip.close()

第三行代码是对 os.listdir() 的调用,它显示当前目录只有一个文件 data.zip。
接下来,以读取模式下关上 data.zip 并调用 .extract() 从中提取 file1.py。.extract() 返回提取文件的残缺文件门路。因为没有指定门路,.extract() 会将 file1.py 提取到当前目录。

下一行打印一个目录列表,显示当前目录当初包含除原始存档文件之外的存档文件。之后显示了如何将整个存档提取到指定目录中。.extractall() 创立 extract_dir 并将 data.zip 的内容提取到其中。最初一行敞开 ZIP 存档文件。

从加密的文档提取数据

zipfile 反对提取受密码保护的 ZIP。要提取受密码保护的 ZIP 文件,请将明码作为参数传递给 .extract() 或.extractall() 办法:

>>> import zipfile

>>> with zipfile.ZipFile('secret.zip', 'r') as pwd_zip:
...     # 从加密的文档提取数据
...     pwd_zip.extractall(path='extract_dir', pwd='Quish3@o')

将以读取模式关上 secret.zip 存档。明码提供给 .extractall(),并且压缩文件内容被提取到 extract_dir。因为 with 语句,在实现提取后,存档文件会主动敞开。

创立新的存档文件

要创立新的 ZIP 存档,请以写入模式(w)关上 ZipFile 对象并增加要归档的文件:

>>> import zipfile

>>> file_list = ['file1.py', 'sub_dir/', 'sub_dir/bar.py', 'sub_dir/foo.py']
>>> with zipfile.ZipFile('new.zip', 'w') as new_zip:
...     for name in file_list:
...         new_zip.write(name)

在该示例中,new_zip 以写入模式关上,file_list 中的每个文件都增加到存档文件中。with 语句完结后,将敞开 new_zip。以写入模式关上 ZIP 文件会删除压缩文件的内容并创立新存档文件。

要将文件增加到现有的存档文件,请以追加模式关上 ZipFile 对象,而后增加文件:

>>> with zipfile.ZipFile('new.zip', 'a') as new_zip:
...     new_zip.write('data.txt')
...     new_zip.write('latin.txt')

这里关上在上一个示例中以追加模式创立的 new.zip 存档。在追加模式下关上 ZipFile 对象容许将新文件增加到 ZIP 文件而不删除其以后内容。将文件增加到 ZIP 文件后,with 语句将脱离上下文并敞开 ZIP 文件。

关上 TAR 存档文件

TAR 文件是像 ZIP 等未压缩的文件存档。它们能够应用 gzip,bzip2 和 lzma 压缩办法进行压缩。TarFile 类容许读取和写入 TAR 存档。
上面是从存档中读取:

import tarfile

with tarfile.open('example.tar', 'r') as tar_file:
    print(tar_file.getnames())

tarfile 对象像大多数相似文件的对象一样关上。它们有一个 open() 函数,它采纳一种模式来确定文件的打开方式。
应用“r”,“w”或“a”模式别离关上未压缩的 TAR 文件以进行读取,写入和追加。要关上压缩的 TAR 文件,请将模式参数传递给 tarfile.open(),其格局为 filemode [:compression]。下表列出了能够关上 TAR 文件的可能模式:


.open() 默认为 ’r’ 模式。要读取未压缩的 TAR 文件并检索其中的文件名,请应用 .getnames():

>>> import tarfile

>>> tar = tarfile.open('example.tar', mode='r')
>>> tar.getnames()
['CONTRIBUTING.rst', 'README.md', 'app.py']

这以列表的形式返回存档中内容的名字。

留神:为了向你展现如何应用不同的 tarfile 对象办法,示例中的 TAR 文件在交互式 REPL 会话中手动关上和敞开。
通过这种形式与 TAR 文件交互,你能够查看运行每个命令的输入。通常,你可能心愿应用上下文管理器来关上相似文件的对象。

此外能够应用非凡属性拜访存档中每个条目标元数据:

>>> for entry in tar.getmembers():
...     print(entry.name)
...     print('Modified:', time.ctime(entry.mtime))
...     print('Size    :', entry.size, 'bytes')
...     print()
CONTRIBUTING.rst
 Modified: Sat Nov  1 09:09:51 2018
 Size    : 402 bytes

README.md
 Modified: Sat Nov  3 07:29:40 2018
 Size    : 5426 bytes

app.py
 Modified: Sat Nov  3 07:29:13 2018
 Size    : 6218 bytes

在此示例中,循环遍历 .getmembers() 返回的文件列表,并打印出每个文件的属性。.getmembers() 返回的对象具备能够通过编程形式拜访的属性,例如归档中每个文件的名称,大小和上次批改工夫。在读取或写入存档后,必须敞开它以开释系统资源。

从 TAR 存档中提取文件

在本节中,你将学习如何应用以下办法从 TAR 存档中提取文件:


.extract()
.extractfile()
.extractall()

要从 TAR 存档中提取单个文件,请应用 extract(),传入文件名:>>> tar.extract('README.md')
>>> os.listdir('.')
['README.md', 'example.tar']

README.md 文件从存档中提取到文件系统。调用 os.listdir() 确认 README.md 文件已胜利提取到当前目录中。要从存档中解压缩或提取所有内容,请应用 .extractall():

>>> tar.extractall(path="extracted/")

.extractall() 有一个可选的 path 参数来指定解压缩文件的去向。这里,存档被提取到 extracted 目录中。以下命令显示已胜利提取存档:

$ ls
example.tar  extracted  README.md

$ tree
.
├── example.tar
├── extracted
|   ├── app.py
|   ├── CONTRIBUTING.rst
|   └── README.md
└── README.md

1 directory, 5 files

$ ls extracted/
app.py  CONTRIBUTING.rst  README.md

要提取文件对象以进行读取或写入,请应用 .extractfile(),它接管 文件名或 TarInfo 对象作为参数。.extractfile() 返回一个能够读取和应用的类文件对象:

>>> f = tar.extractfile('app.py')
>>> f.read()
>>> tar.close()

关上的存档应在读取或写入后始终敞开。要敞开存档,请在存档文件句柄上调用 .close(),或在创立 tarfile 对象时应用 with 语句,以便在实现后主动敞开存档。这将开释系统资源,并将你对存档所做的任何更改写入文件系统。

创立新的 TAR 存档

创立新的 TAR 存档,你能够这样操作:

>>> import tarfile

>>> file_list = ['app.py', 'config.py', 'CONTRIBUTORS.md', 'tests.py']
>>> with tarfile.open('packages.tar', mode='w') as tar:
...     for file in file_list:
...         tar.add(file)

>>> # Read the contents of the newly created archive
>>> with tarfile.open('package.tar', mode='r') as t:
...     for member in t.getmembers():
...         print(member.name)
app.py
config.py
CONTRIBUTORS.md
tests.py

首先,你要创立要增加到存档的文件列表,这样你就不用手动增加每个文件。
下一行应用 with 光线文管理器在写入模式下关上名为 packages.tar 的新存档。以写入模式(’w’)关上存档使你能够将新文件写入存档。将删除存档中的所有现有文件,并创立新存档。

创立并填充存档后,with 上下文管理器会主动敞开它并将其保留到文件系统。最初三行关上刚刚创立的存档,并打印出其中蕴含的文件的名称。
要将新文件增加到现有存档,请以追加模式(’a’)关上存档:

>>> with tarfile.open('package.tar', mode='a') as tar:
...     tar.add('foo.bar')

>>> with tarfile.open('package.tar', mode='r') as tar:
...     for member in tar.getmembers():
...         print(member.name)
app.py
config.py
CONTRIBUTORS.md
tests.py
foo.bar

在追加模式下关上存档容许你向其增加新文件而不删除其中已存在的文件。
应用压缩存档
tarfile 能够读取和写入应用 gzip,bzip2 和 lzma 压缩的 TAR 存档文件。要读取或写入压缩存档,请应用 tarfile.open(),为压缩类型传递适当的模式。
例如,要读取或写入应用 gzip 压缩的 TAR 存档的数据,请别离应用 ‘r:gz’ 或 ‘w:gz’ 模式:

>>> files = ['app.py', 'config.py', 'tests.py']
>>> with tarfile.open('packages.tar.gz', mode='w:gz') as tar:
...     tar.add('app.py')
...     tar.add('config.py')
...     tar.add('tests.py')

>>> with tarfile.open('packages.tar.gz', mode='r:gz') as t:
...     for member in t.getmembers():
...         print(member.name)
app.py
config.py
tests.py

‘w:gz’ 以写模式模式关上 gzip 压缩的存档,’r:gz’ 以读模式关上 gzip 压缩的存档。无奈在追加模式下关上压缩存档。要将文件增加到压缩存档,你必须创立新存档。

一个更简略的形式创立存档

Python 规范库还反对应用 shutil 模块中的高级办法创立 TAR 和 ZIP 存档。shutil 中的归档实用工具容许你创立,读取和提取 ZIP 和 TAR 归档。这些实用工具依赖于较底层的 tarfile 和 zipfile 模块。

应用 shutil.make_archive() 创立存档

shutil.make_archive() 至多接管两个参数:归档的名称和归档格局。

默认状况下,它将当前目录中的所有文件压缩为 format 参数中指定的归档格局。你能够传入可选的 root_dir 参数来压缩不同目录中的文件。
.make_archive() 反对 zip,tar,bztar 和 gztar 存档格局。

以下是应用 shutil 创立 TAR 存档的办法:

import shutil

# shutil.make_archive(base_name, format, root_dir)
shutil.make_archive('data/backup', 'tar', 'data/')

这将复制 data / 中的所有内容,并在文件系统中创立名为 backup.tar 的存档并返回其名称。要提取存档,请调用 .unpack_archive():

shutil.unpack_archive('backup.tar', 'extract_dir/')

调用 .unpack_archive() 并传入存档名称和目标目录,将 backup.tar 的内容提取到 extract_dir/ 中。ZIP 存档能够以雷同的形式创立和提取。

读取多个文件
Python 反对通过 fileinput 模块从多个输出流或文件列表中读取数据。此模块容许你疾速轻松地循环遍历一个或多个文本文件的内容。以下是应用 fileinput 的典型办法:

import fileinput
for line in fileinput.input()
    process(line)

fileinput 默认从传递给 sys.argv 的命令行参数获取其输出。
应用 fileinput 循环遍历多个文件
让咱们应用 fileinput 构建一个一般的 UNIX 工具 cat 的原始版本。cat 工具按程序读取文件,将它们写入规范输入。当在命令行参数中给出多个文件时,cat 将连贯文本文件并在终端中显示后果:

# File: fileinput-example.py
import fileinput
import sys

files = fileinput.input()
for line in files:
    if fileinput.isfirstline():
        print(f'\n--- Reading {fileinput.filename()} ---')
    print('->' + line, end='')
print()

在当前目录中有两个文本文件,运行此命令会产生以下输入:

$ python3 fileinput-example.py bacon.txt cupcake.txt
--- Reading bacon.txt ---
 -> Spicy jalapeno bacon ipsum dolor amet in in aute est qui enim aliquip,
 -> irure cillum drumstick elit.
 -> Doner jowl shank ea exercitation landjaeger incididunt ut porchetta.
 -> Tenderloin bacon aliquip cupidatat chicken chuck quis anim et swine.
 -> Tri-tip doner kevin cillum ham veniam cow hamburger.
 -> Turkey pork loin cupidatat filet mignon capicola brisket cupim ad in.
 -> Ball tip dolor do magna laboris nisi pancetta nostrud doner.

--- Reading cupcake.txt ---
 -> Cupcake ipsum dolor sit amet candy I love cheesecake fruitcake.
 -> Topping muffin cotton candy.
 -> Gummies macaroon jujubes jelly beans marzipan.

fileinput 容许你检索无关每一行的更多信息,例如它是否是第一行 (.isfirstline()),行号(.lineno()) 和文件名(.filename())。你能够在 这里 读更多对于它的内容。

总结
你当初晓得如何应用 Python 对文件和文件组执行最常见的操作。你曾经理解应用不同的内置模块来读取,查找和操作文件。

退出移动版