Python文件操作方法总结

曾经终败给现在 2022-11-26 06:52 347阅读 0赞

1.获取目录列表

使用os模块
Python2.7中使用 os.listdir() 或 在Python 3.x 中使用 os.scandir() 。 如果你还想获取文件和目录属性(如文件大小和修改日期),那么 os.scandir() 则是首选的方法。

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

    import os
    entries = os.listdir(‘目录名’) #结果为列表
    for entry in entries:

    1. print(entry)
  • os.scandir() 调用时返回一个迭代器而不是一个列表

    import os
    entries = os.scandir(‘目录名’)
    print(entries)

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

  1. import os
  2. with os.scandir('目录名') as entries:
  3. for entry in entries:
  4. print(entry.name)

这里 os.scandir() 和with语句一起使用,因为它支持上下文管理协议。使用上下文管理器关闭迭代器并在迭代器耗尽后自动释放获取的资源。

  • pathlib.Path() 返回的是 PosixPath 或 WindowsPath 对象,这取决于操作系统。

    from pathlib import Path

    entries = Path(‘my_directory’)
    for entry in entries.iterdir():

    1. print(entry.name)

pathlib 提供了一组类,以简单并且面向对象的方式提供了路径上的大多数常见的操作。使用 pathlib 比起使用 os 中的函数更加有效。和 os 相比,使用 pathlib 的另一个好处是减少了操作文件系统路径所导入包或模块的数量。






















函数 描述
os.listdir() 以列表的方式返回目录中所有的文件和文件夹
os.scandir() 返回一个迭代器包含目录中所有的对象,对象包含文件属性信息
pathlib.Path().iterdir() 返回一个迭代器包含目录中所有的对象,对象包含文件属性信息

2.列出目录中的所有文件

  • os.scandir()列出目录中的文件

    import os

    basepath = ‘目录名’
    with os.scandir(basepath) as entries:

    1. for entry in entries:
    2. if entry.is_file():
    3. print(entry.name)

对 ScandirIterator 的每一项调用 entry.isfile() ,如果返回 True 则表示这一项是一个文件。

  • pathlib.Path() 列出一个目录中的文件

    from pathlib import Path

    basepath = Path(‘my_directory’)
    for entry in basepath.iterdir():

    1. if entry.is_file():
    2. print(entry.name)

在 .iterdir() 产生的每一项调用 .is_file()

如果将for循环和if语句组合成单个生成器表达式,则上述的代码可以更加简洁。
修改后的版本如下:

  1. from pathlib import Path
  2. basepath = Path('my_directory')
  3. files_in_basepath = (entry for entry in basepath.iterdir() if entry.is_file())
  4. for item in files_in_basepath:
  5. print(item.name)

3.列出子目录

如果要列出子目录而不是文件,请使用下面的方法。

  • os.listdir()和os.path()

    import os

    basepath = ‘my_directory’
    for entry in os.listdir(basepath):

    1. if os.path.isdir(os.path.join(basepath, entry)):
    2. print(entry)
  • os.scandir()

    import os

    basepath = ‘my_directory’
    with os.scandir(basepath) as entries:

    1. for entry in entries:
    2. if entry.is_dir():
    3. print(entry.name)

此处在 os.scandir() 返回的每一项上调用 .is_dir() 。如果这项是目录,则 is_dir() 返回 True,并打印出目录的名称。

  • pathlib.Path()

    from pathlib import Path

    basepath = Path(‘my_directory’)
    for entry in basepath.iterdir():

    1. if entry.is_dir():
    2. print(entry.name)

在 .iterdir() 迭代器返回的每一项上调用 is_dir() 检查是文件还是目录。如果该项是目录,则打印其名称,并且生成的输出

4.获取文件属性

获取 my_directory 中文件的最后修改时间

  1. import os
  2. with os.scandir('my_directory') as entries:
  3. for entry in entries:
  4. info = entry.stat()
  5. print(info.st_mtime)

os.scandir() 返回一个 ScandirIterator 对象。ScandirIterator 对象中的每一项有 .stat() 方法能获取关于它指向文件或目录的信息。.stat() 提供了例如文件大小和最后修改时间的信息。在上面的示例中,代码打印了 st_time 属性,该属性是上次修改文件内容的时间

  1. from pathlib import Path
  2. basepath = Path('my_directory')
  3. for entry in basepath.iterdir():
  4. info = entry.stat()
  5. print(info.st_mtime)

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

  1. mport datetime
  2. from pathlib import Path
  3. def timestamp2datetime(timestamp, convert_to_local=True, utc=8, is_remove_ms=True)
  4. """
  5. 转换 UNIX 时间戳为 datetime对象
  6. :param timestamp: 时间戳
  7. :param convert_to_local: 是否转为本地时间
  8. :param utc: 时区信息,中国为utc+8
  9. :param is_remove_ms: 是否去除毫秒
  10. :return: datetime 对象
  11. """
  12. if is_remove_ms:
  13. timestamp = int(timestamp)
  14. dt = datetime.datetime.utcfromtimestamp(timestamp)
  15. if convert_to_local:
  16. dt = dt + datetime.timedelta(hours=utc)
  17. return dt
  18. def convert_date(timestamp, format='%Y-%m-%d %H:%M:%S'):
  19. dt = timestamp2datetime(timestamp)
  20. return dt.strftime(format)
  21. basepath = Path('my_directory')
  22. for entry in basepath.iterdir():
  23. if entry.is_file()
  24. info = entry.stat()
  25. print('{} 上次修改时间为 {}'.format(entry.name, convert_date(info.st_mtime)))

首先得到 my_directory 中文件的列表以及它们的属性,然后调用 convert_date() 来转换文件最后修改时间让其以一种人类可读的方式显示。convert_date() 使用 .strftime() 将datetime类型转换为字符串。

5.创建目录






















方法 描述
os.mkdir() 创建单个子目录
os.makedirs() 创建多个目录,包括中间目录
Pathlib.Path.mkdir() 创建单个或多个目录
  • 单目录

    from pathlib import Path

    p = Path(‘example_directory’)
    try:

    1. p.mkdir()

    except FileExistsError as e:

    1. print(e)

或者,你可以给 .mkdir() 传入 exist_ok=True 参数来忽略 FileExistsError 异常:

  1. from pathlib import Path
  2. p = Path('example_directory')
  3. p.mkdir(exist_ok=True)

如果目录已存在,则不会引起错误。

  • 多目录
    os.makedirs() 和 os.mkdir() 类似。两者之间的区别在于,os.makedirs() 不仅可以创建单独的目录,还可以递归的创建目录树。换句话说,它可以创建任何必要的中间文件夹,来确保存在完整的路径。

    import os

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

上述代码创建了 2018/10/05 的目录结构并为所有者和组用户提供读、写和执行权限。默认的模式为 0o777 ,增加了其他用户组的权限。

另一个方式创建多个目录是使用 pathlib.Path 的 .mkdir() :

  1. from pathlib import Path
  2. p = Path('2018/10/05')
  3. p.mkdir(parents=True, exist_ok=True)

通过给 Path.mkdir() 传递 parents=True 关键字参数使它创建 05 目录和使其路径有效的所有父级目录。

在默认情况下,os.makedirs() 和 pathlib.Path.mkdir() 会在目标目录存在的时候抛出 OSError 。通过每次调用函数时传递 exist_ok=True 作为关键字参数则可以覆盖此行为(从Python3.2开始)。

6.文件名模式匹配

下面这些是你可以使用的方法和函数:

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

  • .startswith() 和 .endswith()字符串方法
    遍历并使用 .endswith() 来打印所有扩展名为 .txt 的文件名。

    import os

    for f_name in os.listdir(‘some_directory’):

    1. if f_name.endswith('.txt'):
    2. print(f_name)
  • fnmatch 进行简单文件名模式匹配
    字符串方法匹配的能力是有限的。fnmatch 有对于模式匹配有更先进的函数和方法。
    使用 fnmatch.fnmatch() ,这是一个支持使用 * 和 ? 等通配符的函数

    import os
    import fnmatch

    for f_name in os.listdir(‘some_directory’):

    1. if fnmatch.fnmatch(f_name, '*.txt'):
    2. print(f_name)

查找目录中所有 .txt 文件

  • 更先进的模式匹配
    假设你想要查找符合特定条件的 .txt 文件。例如,你可能指向找到包含单次 data 的 .txt文件,一组下划线之间的数字,以及文件名中包含单词 backup 。就类似于 data_01_backup, data_02_backup, 或 data_03_backup

fnmatch.fnmatch()函数

  1. import os
  2. import fnmatch
  3. for f_name in os.listdir('some_directory'):
  4. if fnmatch.fnmatch(f_name, 'data_*_backup.txt'):
  5. print(f_name)

就仅仅打印出匹配 data_*_backup.txt 模式的文件名称。模式中的 * 将匹配任何字符,因此运行这段代码则将查找文件名以 data 开头并以 backup.txt 的所有文本文件。

7.遍历目录和处理文件

一个常见的编程任务是遍历目录树并处理目录树中的文件。让我们来探讨一下如何使用内置的Python函数 os.walk() 来实现这一功能。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() 在每个循环中返回三个值:
当前文件夹的名称
当前文件夹中子文件夹的列表
当前文件夹中文件的列表

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

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

参考文章:
https://zhuanlan.zhihu.com/p/56909212

发表评论

表情:
评论列表 (有 0 条评论,347人围观)

还没有评论,来说两句吧...

相关阅读