《接口自动化测试框架》代码片段 - 文件和目录操作封装

news2025/5/18 5:01:09

抛砖引玉

在Python中,文件和目录的操作是一项基础且频繁的任务。

Python提供了一系列强大的内置函数和模块,使得这些操作变得既简单又高效。


这些工具极大地简化了对文件和目录的各种操作,从创建新文件、读取数据、写入内容,到删除旧文件、管理目录结构,都变得轻而易举。


在之前的文章中已经对这部分内容做了详细的介绍,本次意在抛砖引玉,不在****重复自我


本次将为大家展示一个实用的工具类,这个工具类是《接口自动化框架(付费)》中的一部分,专门用于封装文件和目录操作的相关功能。


通过这个工具类,你可以更加高效地管理测试数据、读取配置文件以及执行其他与文件和目录相关的操作。希望这个工具类能够对你的工作有所帮助。

历史文章:Python 3 OS标准库学习笔记速查表

历史文章:Python 3 Shutil标准库学习笔记速查表

历史文章:Python 3 Pathlib标准库学习笔记速查表

框架文章:完美落地的自动化测试框架:智能生成?业务依赖?动态替换?报告构建?你来,这儿有!

注意:框架暂不开源,66R包执行,可免费讲解。

请添加图片描述


文件操作

1.打开文件

Python中的open()函数是文件操作的起点。

它接受三个主要参数:文件名称、模式、和编码

文件名称是你要操作的文件的字符串路径;

模式则决定了如何打开文件。常见的模式有:

  • 'r':只读模式,文件必须存在。
  • 'w':写入模式,如果文件存在则会被覆盖,不存在则创建新文件。
  • 'a':追加模式,如果文件存在,则内容会被追加到文件末尾,不存在则创建新文件。
  • 'x':独占模式,如果文件已存在,则操作会失败。
  • 此外,还有'b''t'模式,分别表示二进制和文本模式。
  • 通常,如果不指定模式,则默认为't'(文本模式)。

编码则决定了以什么编码格式读取文件中的内容,默认是UTF-8

例如:

file.txt文件内容

Hello World,Hello Python~
Hello World,Hello Python~
Hello World,Hello Python~

example01.py

with open('file.txt', 'r') as f:
    content = f.read()
    print(content)
    # Hello World,Hello Python~
    # Hello World,Hello Python~
    # Hello World,Hello Python~

这里使用了 with 语句,它可以确保文件在操作完成后被正确关闭,即使在写入过程中发生异常也是如此。


2.读取文件

读取文件通常使用read()方法,它读取文件的全部内容并返回一个字符串。

如果要按行读取,可以使用readline()readlines()方法。

例如:

with open('file.txt', 'r') as f:
    content = f.readline()
    print(content)    # Hello World,Hello Python~


with open('file.txt', 'r') as f:
    content = f.readlines()
    print(content)    # ['Hello World,Hello Python~\n', 'Hello World,Hello Python~\n', 'Hello World,Hello Python~']


3.写入文件

写入文件使用write()方法,它接受一个字符串参数,并将该字符串写入文件。

with open('file.txt', 'a') as f:
    f.write('New Hello World,Hello Python~\n')


目录操作

Python的os模块提供了许多用于目录操作的函数。

1.创建目录

使用os.makedirs()函数可以创建目录。如果目录已存在,可以设置exist_ok=True来避免引发异常。

import os
os.makedirs('测试文件夹')    # 当前目录下不存在“测试文件夹”时创建,否则抛出“FileExistsError”异常

os.makedirs('测试文件夹', exist_ok=True)    # 当前目录不存在则创建,否则忽略创建


2.删除目录

使用os.rmdir()函数可以删除空目录。如果要删除非空目录及其内容,可以使用shutil.rmtree()函数。

import os
os.rmdir('测试文件夹')  # 仅当目录为空时才有效

或者:

import shutil
shutil.rmtree('测试文件夹')  # 删除目录及其内容


3.获取当前工作目录

使用os.getcwd()函数可以获取当前Python脚本的工作目录。

import os

current_dir = os.getcwd()
print(current_dir)  # /Users/xxxx/PythonWorkspace/第49课:第三方库/CASE05:OS


4.改变当前工作目录

使用os.chdir()函数可以改变当前工作目录。

import os

os.chdir('/path/to/directory')


5.列出目录内容

使用os.listdir()函数可以列出指定目录中的所有文件和子目录。

import os

contents = os.listdir('.')  # 列出当前目录内容
print(contents) # ['file.txt', 'FileUtils.py', 'example01.py', '测试文件夹']


路径操作

Python的os.path模块提供了许多用于路径操作的函数,如拼接路径、判断路径是否存在、获取路径的各部分等。

1.路径拼接
import os

path = os.path.join('dir1', 'dir2', 'file.txt')
print(path) # dir1/dir2/file.txt


2.路径分裂
paths = os.path.split(path)
# 将路径和最后一层文件或目录分裂成元祖
print(paths)    # ('dir1/dir2', 'file.txt')


3.路径判断
# 判断路径是否存在
if os.path.exists("./file.txt"):
    print("路径存在")   # 路径存在
else:
    print("路径不存在")

# 判断路径是否为目录
if os.path.isdir("./file.txt"):
    print("路径是目录")
else:
    print("路径不是目录") # 路径不是目录

# 判断路径是否为文件
if os.path.isfile("./file.txt"):
    print("路径是文件")  # 路径是文件
else:
    print("路径不是文件")


代码封装

# -*- coding: utf-8 -*-
"""
@Author  : yangkai
@Email   : 807440781@qq.com
@Project : KKNOBUG-API
@Module  : FakeDataHook.py
@DateTime: 2024/5/11 22:29
"""

import os
import shutil
import zipfile
from datetime import datetime


class FileUtils:
    """
    文件/目录操作工具类封装
    1.在指定路径下创建目录(路径不存在则创建返回True,路径存在则不创建返回False)
    2.在指定路径下创建文件(文件不存在则创建返回True,文件存在则不创建返回False)
    3.检查指定文件路径最后修改日期时间(文件不存在则抛出异常,文件存在则返回最后修改日期时间)
    4.获取指定文件大小(文件不存在则抛出异常,文件存在则返回最后修改日期时间)
    5.检查指定路径是不是目录(是目录则返回True,不是目录则返回False)
    6.检查指定路径是不是文件(是文件则返回True,不是文件则返回False)
    7.获取指定路径下最后创建的文件名称(路径不存在或路径下没有文件抛出异常,路径存在则返回最后创建的文件名称)
    8.获取指定路径下最后创建的目录名称(路径不存在或路径下没有文件抛出异常,路径存在则返回最后创建的目录名称)
    9.删除指定路径的文件(路径不存在时抛出异常,删除成功时返回True)
    10.删除指定路径的目录(路径不存在时抛出异常,删除成功时返回True)
    11.获取指定路径下所有子文件列表(每一个子文件以完整路径返回)
    12.拷贝目标路径下的所有文件或目录到指定路径下(拷贝成功返回True,失败或异常返回False)
    13.将目标路径下的所有文件,压缩到指定路径的压缩文件中
    """
    @staticmethod
    def create_directory(path: str) -> bool:
        """
        在指定路径下创建目录(路径不存在则创建返回True,路径存在则不创建返回False)
        :param path: 目录路径
        :return: 如果目录成功创建,则返回True;如果目录已存在,则返回False
        """
        if not os.path.exists(path):
            os.makedirs(path)
            return True
        return False

    @staticmethod
    def create_file(file_path: str) -> bool:
        """
        在指定路径下创建文件(文件不存在则创建返回True,文件存在则不创建返回False)
        :param file_path: 文件路径
        :return: 如果文件成功创建,则返回True;如果文件已存在,则返回False
        """
        if not os.path.exists(file_path):
            with open(file_path, 'w') as file:
                file.write('')
            return True
        return False

    @staticmethod
    def get_last_modified_time(file_path: str) -> datetime:
        """
        检查指定文件路径最后修改日期时间(文件不存在则抛出异常,文件存在则返回最后修改日期时间)
        :param file_path: 文件路径
        :return: 文件的最后修改日期时间
        :raise FileNotFoundError: 如果文件不存在
        """
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"文件或目录不存在: {file_path}")
        return datetime.fromtimestamp(os.path.getmtime(file_path))

    @staticmethod
    def get_file_size(file_path: str, unit: str = 'B') -> float:
        """
        获取指定文件大小(文件不存在则抛出异常,文件存在则返回最后修改日期时间)并转换为指定单位
        :param file_path: 文件路径
        :param unit: 目标单位,可以是 'B' (字节), 'KB' (千字节), 'MB' (兆字节), 'GB' (吉字节) 等
        :return: 文件大小(转换后的单位,保留两位小数后四舍五入,如果换算单位过大,文件过小,得出的结果或可能是0.0)
        :raise FileNotFoundError: 如果文件不存在
        """
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"文件或目录不存在: {file_path}")

        file_size_bytes = os.path.getsize(file_path)

        # 定义单位转换的映射
        unit_mapping = {
            'B': 1,
            'KB': 1024,
            'MB': 1024 * 1024,
            'GB': 1024 * 1024 * 1024,
            # 可以根据需要添加更多单位
        }

        if unit not in unit_mapping:
            raise ValueError(f"给定换算单位无效,必须是其中之一: {', '.join(unit_mapping.keys())}")

        # 转换文件大小到指定单位
        file_size_unit = round(file_size_bytes / unit_mapping[unit], 2)

        return file_size_unit

    @staticmethod
    def is_directory(path: str) -> bool:
        """
        检查指定路径是不是目录(是目录则返回True,不是目录则返回False)
        :param path: 路径
        :return: 如果是目录则返回True,否则返回False
        """
        return os.path.isdir(path)

    @staticmethod
    def is_file(path: str) -> bool:
        """
        检查指定路径是不是文件(是文件则返回True,不是文件则返回False)
        :param path: 路径
        :return: 如果是文件则返回True,否则返回False
        """
        return os.path.isfile(path)

    @staticmethod
    def get_latest_file_name(directory_path: str) -> str:
        """
        获取指定路径下最后创建的文件名称(路径不存在或路径下没有文件抛出异常,路径存在则返回最后创建的文件名称)
        :param directory_path: 目录路径
        :return: 最后创建的文件名称
        :raise FileNotFoundError: 如果路径不存在或路径下没有文件
        """
        if not os.path.exists(directory_path) or not os.path.isdir(directory_path):
            raise FileNotFoundError(f"目录不存在: {directory_path}")
        # 获取目录中的所有文件
        files = [f for f in os.listdir(directory_path) if os.path.isfile(os.path.join(directory_path, f))]
        if not files:
            raise FileNotFoundError(f"目录中不存在文件: {directory_path}")
        # 按创建时间排序,取最后创建的文件
        latest_file = max(files, key=lambda f: os.path.getctime(os.path.join(directory_path, f)))
        return latest_file

    @staticmethod
    def get_latest_dir_name(path: str) -> str:
        """
        获取指定路径下最后创建的目录名称(路径不存在或路径下没有文件抛出异常,路径存在则返回最后创建的目录名称)
        :param path:
        :return:
        """
        latest_dir = None
        latest_time = 0

        # 遍历指定目录下的所有子目录
        for entry in os.scandir(path):
            if entry.is_dir(follow_symlinks=False):
                # 获取目录的创建时间
                dir_time = entry.stat().st_ctime

                # 比较时间,如果当前目录创建时间晚于之前记录的,则更新记录
                if dir_time > latest_time:
                    latest_time = dir_time
                    latest_dir = entry.name

        return latest_dir

    @staticmethod
    def delete_file(path: str) -> bool:
        """
        删除指定路径的文件(路径不存在时抛出异常,删除成功时返回True)
        :param path:
        :return:
        """
        try:
            # 删除文件
            os.remove(path)
            return True
        except OSError as e:
            # 如果文件不存在或无法删除,将捕获异常
            raise OSError(f"文件删除时出错: {e}")

    @staticmethod
    def delete_directory(directory_path: str) -> bool:
        """
        删除指定路径的目录(路径不存在时抛出异常,删除成功时返回True)
        :param directory_path:
        :return:
        """
        try:
            shutil.rmtree(directory_path)
            return True
        except NotADirectoryError as nde:
            raise TypeError(f"路径必须是一个目录:{nde}")

    @staticmethod
    def get_all_files(file_path: str) -> list:
        """
        获取指定路径下所有子文件列表(每一个子文件以完整路径返回)
        :param file_path: 目录路径
        :return:
        """
        filename = []
        # 获取所有文件下的子文件名称
        for root, dirs, files in os.walk(file_path):
            for _file_path in files:
                path = os.path.join(root, _file_path)
                filename.append(path)
        return filename

    @staticmethod
    def copy_directory(src_path: str, dst_path: str) -> bool:
        """
        拷贝目标路径下的所有文件或目录到指定路径下(拷贝成功返回True,失败或异常返回False)
        @param src_path: 原目录
        @param dst_path: 新目录
        """
        if not os.path.exists(src_path):
            return False
        try:
            if os.path.isdir(src_path):
                shutil.copytree(src=src_path, dst=dst_path, dirs_exist_ok=True)
                return True
            if os.path.isfile(src_path):
                shutil.copy(src=src_path, dst=dst_path)
                return True
            return False
        except:
            return False

    @staticmethod
    def zip_files(zip_file_name: str, zip_dir_path: str) -> str:
        """
        将zip_dir_list路径下的所有文件,压缩到一个zip_file_name的压缩文件中
        :param zip_file_name: 最终压缩文件名称
        :param zip_dir_path:
        :return:
        """
        parent_name = os.path.dirname(zip_dir_path)
        # 压缩文件最后需要close,为了方便我们直接用with
        with zipfile.ZipFile(file=zip_file_name, mode="w", compression=zipfile.ZIP_STORED) as zip:
            for root, dirs, files in os.walk(zip_dir_path):
                for file in files:
                    # 不处理已打开的文件副本
                    if str(file).startswith("~$"):
                        continue
                    filepath = os.path.join(root, file)
                    writepath = os.path.relpath(filepath, parent_name)
                    zip.write(filepath, writepath)
            zip.close()
        return zip_file_name



if __name__ == '__main__':
    # 创建目录,创建成功返回True,创建失败返回False
    # print(FileUtils.create_directory("./new_directory"))

    # 创建文件,创建成功返回True,创建失败返回False
    # print(FileUtils.create_file("./new_directory/new_file.txt"))

    # 获取文件最后修改时间,指定路径不存在则抛出异常,指定路径存在则返回最后修改日期实际
    # print(FileUtils.get_last_modified_time("./new_directory/new_file.txt"))

    # 获取文件大小,保留两位小数后四舍五入,如果换算单位过大,文件过小,得出的结果或可能是0.0
    # print(FileUtils.get_file_size("./new_directory/new_file.txt", "KB"))

    # 检查路径是否为目录,是目录返回True,不是目录返回False
    # print(FileUtils.is_directory("./new_directory"))

    # 检查路径是否为文件,是文件返回True,不是文件返回False
    # print(FileUtils.is_file("./new_directory/new_file.txt"))

    # 获取路径下最后创建的文件名称
    # print(FileUtils.get_latest_file_name("/Users/yangkai/KKNOBUG-API/output/logs"))

    # 获取路径下最后创建的目录名称
    # print(FileUtils.get_latest_dir_name("./"))

    # 删除路径下的文件或目录
    # FileUtils.delete_file("./new_directory/new_file.txt")
    # FileUtils.delete_directory("./new_directory")

    # print(FileUtils.__doc__)

    # 获取指定路径下所有的子文件
    # print(FileUtils.get_all_files('/Users/yangkai/KKNOBUG-API/output/reports/html/1/test-cases'))

    # 复制目录或文件
    # print(FileUtils.copy_directory(src_path="/Users/yangkai/KKNOBUG-API/output/reports/html/6",
    #                                dst_path="/Users/yangkai/KKNOBUG-API/output/reports/attachment/执行日志"))

    # 压缩文件
    # print(FileUtils.zip_files(zip_file_name="6666.zip", zip_dir_path="/Users/yangkai/KKNOBUG-API/output/reports/html/6"))

    pass

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1798417.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

易语言QQ机器人2.0源码

易语言QQ机器人2.0 效果图源码说明领取源码下期更新预报 效果图 源码说明 .程序集 Smessage, VJ_DirectUI .程序集变量 Format, StringFormat.子程序 _初始化, , , 当基于本类的对象被创建后,此方法会被自动调用.子程序 _销毁, , , 当基于本类的对象被销毁前&#x…

mysql当前状态分析(show status)

文章目录 查看当前线程数据查询连接情况查询缓存相关查询锁相关查询增删改查执行次数查询DDL创建相关 SHOW STATUS 是一个在 MySQL 中用来查看服务器运行状态的命令。它可以帮助你了解服务器的当前性能,包括连接数、表锁定、缓冲区使用情况等信息。 查看当前线程数据…

【Java】解决Java报错:ConcurrentModificationException

文章目录 引言1. 错误详解2. 常见的出错场景2.1 遍历过程中修改集合2.2 使用 Iterator 进行删除操作 3. 解决方案3.1 使用 Iterator 的 remove 方法3.2 使用 CopyOnWriteArrayList3.3 使用 synchronized 块 4. 预防措施4.1 使用线程安全的集合类4.2 使用合适的遍历和修改方法4.…

大模型安全技术实践 | RAG精确应对大模型敏感问题知识幻觉难题

一、引言 在大模型的实际应用落地过程中,会遇到所谓的幻觉(Hallucination)问题。对于语言模型而言,当生成的文本语法正确流畅,但与原文不符(Faithfulness)或事实不符(Factualness&a…

【51单片机】智能百叶窗项目

文章目录 功能演示:前置要求:主要功能:主要模块:主函数代码: 具体的仿真程序和代码程序已经免费放置在资源中,如有需要,可以下载进行操作。 功能演示: 前置要求: 编译软…

气膜建筑的照明设计:智能与高效的完美结合—轻空间

气膜建筑作为一种新型的建筑形式,因其独特的结构和材料,带来了多样化的功能和应用场景。在气膜建筑的设计中,照明设计是一个重要的环节,直接关系到建筑内部的使用体验和能源利用效率。本文将详细探讨气膜建筑的照明设计如何实现智…

QFI 2024年第二季度創羽計畫再次啟動,臺灣分部學員迎來最後的絕佳機會並獲得專案補助資格

Quantum Financial Insights (QFI) 在2024年第二季度的綜合表現不凡,無論是在社群用戶、交易量、綜合獲益值還是股價等方面,都展現出非常出色的優異表現,持續受到各國金融界、財團法人及國內外媒體的密切關注。QFI於正式宣佈,將贈予臺灣分部20個創羽案名額,這是該計畫原先已經結…

快速入门链路追踪sleuth整合zipkin(代码演示)

1、演示项目背景 2、pom.xml 3、启动项目 4、测试 5、保存数据到数据库 6、通过mq保存数据到mysql 7、通过mq保存数据到es 1、演示项目背景 下载zipkin,建议使用2.x版本的,3.x版本的要求jdk高版本。如果自己是1.8,就下载2.x的 下载地…

Win11 ubuntu子系统安装WslRegisterDistribution failed with error: 0x800701bc

执行完这两部,然后再打开ubuntu即可。链接

GitHub生成SSH密钥,使用SSH进行连接

目录 一、生成新的SSH密钥 二、添加新的SSH密钥 三、测试SSH连接 四、SSH密钥密码 五、创建新仓库并推送到github 说明 使用 SSH URL 将 git clone、git fetch、git pull 或 git push 执行到远程存储库时, 须在计算机上生成 SSH 密钥对,并将公钥添加到…

YOLOv10:实时端到端目标检测的新突破

目标检测作为计算机视觉领域的一个核心问题,其关键在于能够在图像中准确识别并定位对象。随着深度学习技术的发展,基于深度神经网络的目标检测方法不断涌现,其中YOLO(You Only Look Once)系列算法以其优异的实时性和准…

共筑安全防线 展望数字未来︱智汇云舟亮相广西网络安全与信息化高峰论坛

“没有网络安全,就没有国家安全”。自网络安全法颁布以来,国家及地方各级政府、企事业单位和社会各界高度重视并积极参与其中,信息系统的建设离不开网络安全体系的保障支撑,尤其在以数字孪生技术实现的综合业务管理平台设计中&…

GAT1399协议分析(10)--视频定义及解析

一、官方定义 二、字段解析 VideoID 类型BasicObjectID 解析参考GAT1399协议分析(8)--ImageInfo字段详解-CSDN博客 InfoKind 采集类型

工具:Linux如何挂载NTFS移动硬盘

从windows平台迁移数据至Linux平台,有时候会用到NTFS文件系统的硬盘,但Linux的file system一般又无法直接兼容NTFS系统。这个就需要用到ntfs-3g插件。 NTFS-3G是一个开源项目, NTFS-3G是为Linux, Android, Mac OS X, FreeBSD, NetBSD, OpenSo…

据阿谱尔调研显示,中国浮法玻璃产量大约占全球总产量的1/3以上

浮法玻璃是一种通过浸入熔融金属表面形成的玻璃板,其制造过程被称为浮法工艺。这一工艺的核心在于将熔化后的玻璃液顺利浮在低熔点的金属(通常是锡)表面上,使得玻璃板具有均匀的厚度和平整的表面。其化学成分主要由二氧化硅、氧化…

信创国产化 | 聚铭网络携手银河麒麟完成产品兼容性互认证

在我国信创国产化战略深入推进的大背景下,聚铭网络与麒麟软件积极响应国家号召,共同致力于软件和操作系统的国产化发展。近日,双方宣布已完成产品兼容性互认证工作,这一成果标志着两家公司在信创国产化道路上迈出了坚实的一步。 …

智能引领医疗新纪元:RFID技术在医疗器械管理中的高端应用

智能引领医疗新纪元:RFID技术在医疗器械管理中的高端应用 随着医疗技术的快速发展,医疗器械在医疗行业中扮演着至关重要的角色。然而,如何有效地管理这些医疗器械,确保其安全、准确、及时地服务于患者,一直是医疗机构…

DSP问题:TMS320F280049延时和实际不符

1、问题现象 我之前写的一篇点灯文章,发现LED等闪烁频率和设想不一致,延时100ms,实际延时要更长。 2、问题原因 电路中使用的晶振是10MHz,实际代码中配置的是20MHz的晶振。 3、解决方案 修改代码中的晶振配置为10MHz即可。…

俯视角2D游戏_02 子弹对象池

[!NOTE] 对象池 应用场合:这种做法常用于子弹这种会大量产生的对象 ,目的是减少性能的损耗 基本思路:产生的对象是有限的,并且加入到"对象池"的数组中不进行销毁,当需要使用时,再从对象池中提取对象循环利用&#xff0c…

1961. 检查字符串是否为数组前缀 - 力扣

1. 题目 给你一个字符串 s 和一个字符串数组 words ,请你判断 s 是否为 words 的 前缀字符串 。 字符串 s 要成为 words 的 前缀字符串 ,需要满足:s 可以由 words 中的前 k(k 为 正数 )个字符串按顺序相连得到&#xf…