python文件处理之os模块和shutil模块

目录

1.os模块

os.path.exists(path):文件或者目录存在与否判断

os.path.isfile(path):判断是否是文件

os.path.isdir(path):判断是否是文件夹

os.remove(path):尝试删除文件

os.rmdir(path):尝试删除目录

os.mkdir(path):创建目录

os.rename:文件(夹)重命名或剪切

os.getcwd():获取当前工作路径

os.chdir(path):改变当前工作路径

os.listdir(path):获取指定目录下的所有文件(夹)名

os.path.join(__path, *paths):将多个文件(夹)组成一个文件路径

os.path.abspath(path):返回由当前工作目录组成的绝对路径

os.path.isabs(path):判断是否符合绝对路径格式

os.path.dirname(path):获取文件(夹)所在目录

os.path.basename(path):获取文件(夹)名字

os.path.split(path):获取文件(夹)所在目录和名字

os.walk(path):目录深度遍历

os.path.sep宏

os.path.getsize(path):获取文件字节大小

文件目录深度遍历

__file__ :python内置宏:当前代码所在文件的绝对路径

获取当前代码文件所在目录

2.shutil模块

shutil.copyfile文件复制

shutil.move文件剪切

shutil.rmtree删除文件夹


1.os模块

os库中有许多常用的对文件和文件夹处理的函数。

os.path.exists(path):文件或者目录存在与否判断

作用:判断文件或者目录是否存在。若存在返回True,否则返回false。

import os
datapath1 = r"C:\xxxx\xxxx\xxxx"
print(os.path.exists(datapath1))   # False

os.path.isfile(path):判断是否是文件

判断是否是文件。如果path不存在返回False,如果path存在且是文件返回True,path存在且不是文件返回False。

import os
path1 = r"C:"
print(os.path.isfile(path1))  # False,因为是目录
path2 = r"C:\xxxx\xxxx\xxxx\data.txt"
print(os.path.isfile(path2))  # False,因为文件不存在
path3 = r"C:\xxxx\data.txt"
print(os.path.isfile(path3))  # True,因为path存在且是文件

os.path.isdir(path):判断是否是文件夹

作用:判断是否是文件夹。如果path不存在返回False,如果path存在且是文件夹返回True,path存在且不是文件夹返回False。

import os
path1 = r"C:"
print(os.path.isdir(path1))  # True,因为path存在且是目录
path2 = r"C:\xxxx\xxxx\xxxx"
print(os.path.isdir(path2))  # False,因为path不存在
path3 = r"C:\xxxx"
print(os.path.isdir(path3))  # True,因为path存在且是目录
path4 = r"C:\xxxx\data.txt"
print(os.path.isdir(path4))  # False,因为path是文件

os.remove(path):尝试删除文件

如果文件不存在会报错FileNotFoundError,因此需要先判断文件是否存在。如果path存在且不是文件也会报错FileNotFoundError。

import os

path = r"D:\xxxx\xxxx\xxxx\venv\data.txt"
if os.path.exists(path):
    try:
        os.remove(path)
        print(f"删除文件{path}成功")
    except FileNotFoundError as e:
        print(e)
        print(f"{path}是目录不是文件,os.remove函数无法删除")
else:
    print(f"{path} not exist")

os.rmdir(path):尝试删除目录

os.rmdir(path)

  • 如果path不存在则会FileNotFoundError。所以一般建议先判断文件夹存在再调用这个函数。
  • 如果path且为文件,也会报错FileNotFoundError
  • 如果path且为目录,如果目录为空目录,则可以删除,如果不为空则无法删除,报错OSError
import os

path = r"C:\xxxx"
if os.path.exists(path):
    try:
        os.rmdir(path)
        print(f"删除空目录{path}成功")
    except FileNotFoundError as e:
        print(e)
        print(f"删除{path}失败,因为它是文件")
    except OSError as e:
        print(e)
        print(f"删除{path}失败,因为它不是空目录")
else:
    print(f"{path} not exist")

os.mkdir(path):创建目录

  • 如果路径存在则FileExistsError
  • 如果路径不存在则创建路径。但如果路径是几层目录都不存在,则创建会出现FileNotFoundError,比如要创建目录"D:\xxxx\xxxx\xxxx",因为"D:\xxxx\xxxx"是不存在的,所以会报错。
import os

datapath1 = r"C:\xxxx"
if not os.path.exists(datapath1):
    try:
        os.mkdir(datapath1)
    except FileNotFoundError as e:
        print("FileNotFoundError:", e)
else:
    print(datapath1, "已经存在")


datapath2 = r"D:\xxxx\xxxx\xxxx"
if not os.path.exists(datapath2):
    try:
        os.mkdir(datapath2)
    except FileNotFoundError as e:
        print("FileNotFoundError:", e)
else:
    print(datapath2, "已经存在")

自定义创建目录函数,像"D:\xxxx\xxxx\xxxx"这样的目录也能创建

def make_dir(dir_path):
    need_build_dir_list = []
    while True:
        # print(dir_path)
        if os.path.exists(dir_path):
            break
        else:
            need_build_dir_list.append(dir_path)
            dir_path = os.path.dirname(dir_path)
    # print(need_build_dir_list)

    for i in range(len(need_build_dir_list)-1, -1, -1):
        print("创建目录:", need_build_dir_list[i])
        os.mkdir(need_build_dir_list[i])


temp_dir = r"D:\xxxx\xxxx\xxxx"
make_dir(temp_dir)

os.rename:文件(夹)重命名或剪切

os.rename(src, dst)

  • src:是文件或文件夹的名称。 它必须已经存在,否则FileNotFoundError。绝对路径。
  • dst:是要更改的文件或文件夹的新名称。绝对路径。

注意:

  • 如果src是文件,则dst按文件生成。
    • 如果文件src和dst所在的目录相同,则为文件重命名。
    • 如果文件src和dst所在的目录不同,则为文件剪切。
  • 如果src是目录,则dst按目录生成。
    • 如果文件夹src和dst所在的目录相同,则为文件夹重命名。
    • 如果文件夹src和dst所在的目录不同,则为文件夹剪切。

例子1:

import os

if __name__ == "__main__":
    src_name = "D:/projects/clear_market_data/test.csv"
    dst_name = "D:/projects/test2.csv"
    if os.path.exists(src_name):
        os.rename(src_name, dst_name)

例子2:

import os

if __name__ == "__main__":
    src_name = r"C:\xxxx"
    dst_name = r"C:\yyyy.txt"
    if os.path.exists(src_name):
        os.rename(src_name, dst_name)

注意这里将文件夹"xxxx"改成了文件夹"yyyy.txt","yyyy.txt"是文件夹名而不是文件。

os.getcwd():获取当前工作路径

import os

currentWorkPath = os.getcwd()
print(currentWorkPath)  # D:\projects\test

path = os.path.abspath('.')  # 单个点表示当前目录的缩写
print(path)  # D:\projects\test

os.chdir(path):改变当前工作路径

作用:改变当前工作路径。如果目录不存在则FileNotFoundError

import os

currentWorkPath = os.getcwd()
print(currentWorkPath)   # D:\projects\test

try:
    os.chdir(r"D:\test")
    print(os.getcwd())   # D:\test
except FileNotFoundError as e:
    print(e)

os.chdir(currentWorkPath)
print(os.getcwd())   # D:\projects\test

os.listdir(path):获取指定目录下的所有文件(夹)名

作用:索取指定目录下的所有文件夹名和文件名。

如果path不存在则FileNotFoundError。

如果path存在但为文件名则会NotADirectoryError

如果path存在但为文件夹则会返回一个列表,包含该文件夹下的所有文件夹名和文件名。

import os

path = r"C:\xxxx\data.txt"

if os.path.exists(path):
    try:
        filename_list = os.listdir(path)
        print(filename_list)
    except NotADirectoryError as e:
        print(e)
        print(f"获取{path}下的全部文件名失败,因为它不是文件夹")
else:
    print(f"{path} not exist")

获取当前目录下的所有文件(夹)名

import os

# 获取当前目录中的内容
all_files = os.listdir(os.getcwd())
print(all_files)

# 获取当前目录中的内容
filenames = os.listdir(os.curdir)
print(filenames)

os.path.join(__path, *paths):将多个文件(夹)组成一个文件路径

import os

path = os.path.join('users', 'tta', 'Documents', 'python.docx')
print(path)   # users\tta\Documents\python.docx

path = path.replace("\\", "/")
print(path)   # users/tta/Documents/python.docx

imageNames = ["apple.jpg", "orange.jpg", "dog.jpg"]
for image in imageNames:
    pathImage = os.path.join('users', 'tta', 'Documents', image)
    print(pathImage)

os.path.abspath(path):返回由当前工作目录组成的绝对路径

作用:传递path,返回由当前工作目录组成的绝对路径。返回的绝对路径就是是os.getcwd()+path构成。

注意不判断文件存在与否。

import os

cwd = os.getcwd()
file_name = "data.txt"

path1 = cwd + "\\" + file_name
path2 = os.path.abspath("data.txt")

print(path1)  # D:\projects\test\data.txt
print(path2)  # D:\projects\test\data.txt
print(path1 == path2)   # True

dir_name = "xxxx\\xxxx\\xxxx"
path3 = os.path.abspath(dir_name)
print(path3)  # D:\projects\test\xxxx\xxxx\xxxx

os.path.isabs(path):判断是否符合绝对路径格式

作用:判断路径格式是否符合绝对路径格式。

文件(夹)不存在也无所谓,只判断格式是否符合绝对路径

import os

bool1 = os.path.isabs("data.txt")
print(bool1)  # False

bool2 = os.path.isabs(r"D:\xxxx\xxxx\venv\data.txt")
print(bool2)  # True  # 文件不存在也无所谓,只判断格式是否符合绝对路径

bool3 = os.path.isabs(r"D:\xxxx\xxxx")
print(bool2)  # True  # 文件夹不存在也无所谓,只判断格式是否符合绝对路径

os.path.dirname(path):获取文件(夹)所在目录

返回 path 最后一个斜杠之前的所有内容

import os
path = r"D:\xxxx\xxxx\venv\data.txt"
ret1 = os.path.dirname(path)
print(ret1)  # D:\xxxx\xxxx\venv

注意对于目录来说最后有无斜杠时的区别

import os

path = "D:/xxxx/xxxx/venv/"
ret = os.path.dirname(path)
print(ret)  # D:/xxxx/xxxx/venv

path = "D:/xxxx/xxxx/venv"
ret = os.path.dirname(path)
print(ret)  # D:/xxxx/xxxx

os.path.basename(path):获取文件(夹)名字

返回 path 最后一个斜杠之后的所有内容

import os
path = r"D:\xxxx\xxxx\venv\data.txt"

ret2 = os.path.basename(path)
print(ret2)  # data.txt

注意对于目录来说最后有无斜杠时的区别

import os

path = "D:/xxxx/xxxx/venv/"
ret = os.path.basename(path)
print(f"[{ret}]")  # []

path = "D:/xxxx/xxxx/venv"
ret = os.path.basename(path)
print(f"[{ret}]")  # [venv]

os.path.split(path):获取文件(夹)所在目录和名字

相当于获取os.path.dirname(path)和os.path.basename(path)

import os
path = r"D:\xxxx\xxxx\venv\data.txt"

ret3 = os.path.split(path)
print(ret3)  # ('D:\\xxxx\\xxxx\\venv', 'data.txt')

os.walk(path):目录深度遍历

python中os.walk是一个简单易用的文件、目录遍历器,可以帮助我们高效的处理文件、目录方面的事情。

os.walk方法,主要用来遍历一个目录内各个子目录和子文件。

os.walk(top, topdown=True, οnerrοr=None, followlinks=False) 

参数

  • top 是你所要便利的目录的地址
  • topdown 为真,则优先遍历top目录,否则优先遍历top的子目录(默认为开启)
  • onerror 需要一个 callable 对象,当walk需要异常时,会调用
  • followlinks 如果为真,则会遍历目录下的快捷方式(linux 下是 symbolic link)实际所指的目录(默认关闭)

返回值:os.walk 的返回值是一个生成器(generator),也就是说我们需要不断的遍历它,来获得所有的内容。一个三元tupple(dirpath, dirnames, filenames),

  • dirpath 是一个string,第一个为起始路径,代表目录的路径,指的是当前正在遍历的这个文件夹的本身的地址。
  • dirnames 是一个list,第二个为起始路径下的文件夹,包含了dirpath下所有子目录的名字,内容是该文件夹中所有的目录的名字(不包括子目录)
  • filenames 是一个list,第三个是起始路径下的文件,包含了非目录文件的名字,内容是该文件夹中所有的文件(不包括子目录)

这些名字不包含路径信息,如果需要得到全路径,需要使用os.path.join(dirpath, name).

例子

如果我们有如下的文件结构

示例代码

# -*- coding: utf-8 -*-
import os

if __name__ == "__main__":
    dir_path = r"D:\PythonTest\a"
    for root, dirs, files in os.walk(dir_path):
        print("==============")
        print(root)
        print(dirs)
        print(files)

运行结果

==============
D:\PythonTest\a
['b', 'c', 'd']
['4.txt', '5.txt']
==============
D:\PythonTest\a\b
[]
['1.txt', '2.txt']
==============
D:\PythonTest\a\c
[]
['3.txt']
==============
D:\PythonTest\a\d
[]
[]

os.path.sep宏

文件夹分割变量,配合字符串的 split 方法使用。

注意不会判断路径的存在与否。

import os
path = r"D:\xxxx\xxxx\xxxx\venv\data.txt"
result = path.split(os.path.sep)
print(result)  # ['D:', 'xxxx', 'xxxx', 'xxxx', 'venv', 'data.txt']

os.path.getsize(path):获取文件字节大小

返回文件的大小,单位字节。

如果文件不存在则FileNotFoundError

import os

path = r"D:\data\1.txt"
if os.path.exists(path):
    ret = os.path.getsize(path)
    print(path, ret)

文件目录深度遍历

当你传入一个文件夹的路径给 os.path.getsize() 时,则会遇到一个错误,因为os.path.getsize() 是用于获取文件大小的,而不是文件夹的大小。Python 会尝试获取该文件夹(实际上是一个目录项)的大小,但通常目录项本身的大小很小(只包含元数据和可能的默认文件大小),而不是目录中所有文件和子目录的总大小。

要获取文件夹的大小(包括其中的所有文件和子文件夹),你需要编写一个递归函数来遍历目录树并累加所有文件的大小。以下是一个简单的示例:

import os


def get_directory_size(path):
    total_size = 0
    for dir_path, dir_names, file_names in os.walk(path):
        for f in file_names:
            fp = os.path.join(dir_path, f)
            # 跳过如果它是一个符号链接  
            if not os.path.islink(fp):
                total_size += os.path.getsize(fp)
    return total_size


# 使用方法  
folder_path = r'D:\data'
folder_size = get_directory_size(folder_path)
print(f"The size of {folder_path} is {folder_size} bytes.")

__file__ :python内置宏:当前代码所在文件的绝对路径

print(__file__)  # D:\projects\test\main.py

获取当前代码文件所在目录

os.path.abspath(__file__):当前代码文件所在绝对路径

import os

print(__file__)  # D:\projects\test\main.py

this_file_path = os.path.abspath(__file__)
print(this_file_path)  # D:\projects\test\main.py

this_file_path = os.path.abspath(__file__).replace("\\", "/")
print(this_file_path)  # D:/projects/test/main.py

当前代码文件所在目录:os.path.basename(os.path.abspath(__file__))

import os

print(__file__)  # D:\projects\test\main.py

this_file_path = os.path.abspath(__file__).replace("\\", "/")
print(this_file_path)  # D:/projects/test/main.py

print(os.path.basename(this_file_path))  # main.py

print(os.path.dirname(this_file_path))   # D:/projects/test

2.shutil模块

shutil.copyfile文件复制

shutil.copyfile 是 Python 的 shutil 模块中的一个函数,用于将一个文件的内容复制到另一个文件中。

shutil.copyfile(src, dst, follow_symlinks=True)

将名为 src 的文件的内容(不包括元数据)拷贝到名为 dst 的文件,并以尽可能高效的方式返回 dst。

  • src(必需):源文件名称,可包含合法路径。
  • dst(必需):复制到的目标文件名,可包含合法路径。
  • follow_symlinks(可选,默认为 True):
    • 如果为 True,且 src 是一个符号链接(软连接),则复制该符号链接所指向的文件。
    • 如果为 False,且 src 是一个符号链接,则创建一个新的符号链接而不是拷贝链接所指向的文件。

这里我们自定义一个将制定文件复制到指定目录下的函数

import shutil
import os


# 创建目录函数
def make_dir(dir_path):
    need_build_dir_list = []
    while True:
        # print(dir_path)
        if os.path.exists(dir_path):
            break
        else:
            need_build_dir_list.append(dir_path)
            dir_path = os.path.dirname(dir_path)
    # print(need_build_dir_list)

    for i in range(len(need_build_dir_list)-1, -1, -1):
        print("创建目录:", need_build_dir_list[i])
        os.mkdir(need_build_dir_list[i])


# 文件传输函数
def transfer_file(file_path, dst_dir):
    """
    将文件file_path复制到dst_dir目录下
    :param file_path: 文件所在路径,全路径
    :param dst_dir: 要复制的目录下
    :return:
    """
    if not os.path.exists(file_path):
        print(f"{file_path} not exist")
        return
    elif not os.path.isfile(file_path):
        print(f"{file_path} not file")
        return

    if not os.path.exists(dst_dir):
        make_dir(dst_dir)

    save_path = dst_dir + "/" + os.path.basename(file_path)
    shutil.copyfile(file_path, save_path)


if __name__ == "__main__":
    data_path = r"D:\data\1.txt"
    save_dir = r"D:\xxxx\xxxx\xxxx"
    transfer_file(data_path, save_dir)

shutil.move文件剪切

shutil.move(src, dst)

参数:

  • src(必需):源文件或目录的路径。
  • dst(必需):目标位置的路径。

功能描述:

  • 递归地将一个文件或目录移动到另一个位置,并返回新的目标位置。
  • 如果目标是一个目录,则源文件或目录会被移动到该目录中。
  • 如果目标已经存在但不是一个目录,它可能会被覆盖,具体取决于 os.rename() 的语义。

注意事项:

  • 如果目标位置已经存在同名的文件或目录,shutil.move() 默认会抛出 FileExistsError 异常。如果希望覆盖已存在的文件,可能需要自行处理异常或使用其他方式来实现。
  • 在跨文件系统移动文件时,shutil.move() 会使用 copy_function 指定的函数(默认为 shutil.copy2())来复制文件,然后再删除源文件。这可能会导致额外的磁盘 I/O 操作。
  • shutil.move() 不会复制文件的元数据(如修改时间、权限等),除非在跨文件系统移动文件时使用了 copy_function 参数。
import shutil
import os


# 创建目录函数
def make_dir(dir_path):
    need_build_dir_list = []
    while True:
        # print(dir_path)
        if os.path.exists(dir_path):
            break
        else:
            need_build_dir_list.append(dir_path)
            dir_path = os.path.dirname(dir_path)
    # print(need_build_dir_list)

    for i in range(len(need_build_dir_list)-1, -1, -1):
        print("创建目录:", need_build_dir_list[i])
        os.mkdir(need_build_dir_list[i])


# 剪切文件
def move_files(src, dst):
    """
    :param src: 要剪切的文件路径,如果src为目录,则将该目录下所有文件复制到dst
    :param dst: 目标目录。如果dst为文件,则将该文件所在目录作为目标目录。
    :return:
    """
    if not os.path.exists(src):
        print(f"{src} not exist")
        return

    src_file_list = []
    if os.path.isfile(src):
        src_file_list.append(src)
    elif os.path.isdir(src):
        file_name_list = os.listdir(src)
        for file_name in file_name_list:
            file_path = os.path.join(src, file_name)
            if os.path.isfile(file_path):
                src_file_list.append(file_path)
    else:
        return

    print(src_file_list)
    if len(src_file_list) == 0:
        return

    if os.path.isdir(dst):
        save_dir = dst
    else:
        save_dir = os.path.dirname(dst)

    make_dir(save_dir)

    # 判断目标文件是否存在,不存在则移动过来
    for file_path in src_file_list:
        print(f"{file_path} to {save_dir}")
        shutil.move(file_path, save_dir)


data_path = r"D:\data\2.txt"
target_dir = r"D:\xxxx\xxxx\xxxx\1.txt"
move_files(data_path, target_dir)

shutil.rmtree删除文件夹

shutil.rmtree(path)

如果path不存在则会FileNotFoundError

如果path存在但是文件则会NotADirectoryError

如果path存在且是文件夹,无论文件夹是否为空,则会将该path以及下面的所有文件和文件夹删除。

import shutil
import os


# 删除文件夹
def rm_dir_tree(dir_path):
    if os.path.exists(dir_path):
        try:
            shutil.rmtree(dir_path)
            print(f"删除{dir_path}成功")
        except NotADirectoryError as e:
            print("NotADirectoryError:", e)
            print(f"{dir_path} is not directory, is file")
    else:
        print(f"{dir_path} not exist")


data_dir = r"D:\xxxx\xxxx\xxxx\yyyyy\yyyyy"
rm_dir_tree(data_dir)

data_dir = r"D:\xxxx\xxxx\xxxx\1.txt"
rm_dir_tree(data_dir)

data_dir = r"D:\xxxx\xxxx"
rm_dir_tree(data_dir)

end

  • 39
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值