file | 某文件夹【解耦合】下的文件查找功能实现及功能单元测试

文件查找工具

  • 概要
  • 思路
  • OS模块 --- 学习版
    • os.getcwd()
    • os.path.dirname(os.getcwd())
    • os.path.dirname() 和 os.path.basename()
  • OS模块 — 实战版
      • 单元测试
        • 解耦合

概要

  • 梳理业务主逻辑:
  1. 查看存放被采集JSON数据的文件夹内的文件列表【所有 包含文件夹下的文件夹下的文件
    这是本节内容聚焦的点
  2. 和MySQL内记录的信息做比对,判断哪些文件是新文件,需要采集的。
  3. 读取JSON文件,执行ETL操作(读取->写入CSV->写入MySQL(目的地库))。
  4. 将被处理的JSON信息,记录到MySQL数据库(元数据库)

思路

读取某个文件中的文件名--------------------set()

读取数据库中已经处理过的文件名称-----set()
做处理 – 得到未处理过的文件名-----------set()-set()

如何处理?

  • 思路1:集合相减得到的结果是在第一个集合且不在第二个集合中的元素
  • 思路2: for循环

在这里插入图片描述

OS模块 — 学习版

  • 耦合

和固定路径绑定在一起,若是将这部分代码给其他人,他们需要创建对应文件夹才可以使用

# 学习OS 接口模块
import os

# 输出文件下的子文件  - 不包括子文件下的文件 仅返回子文件夹的名称
files = os.listdir(r'E:\pythonProject\ETL\day04_商品数据采集\04_数据\采集JSON')
print(files)

# 输出文件下的子文件 包括子文件夹呢?
# 递归调用
def read_dir(dir):
    results =[]
    files = os.listdir(dir)
    for file in files:
        # 判断是否是目录
        if os.path.isdir(file):
            results += read_dir(dir+'/'+file)
        else:
            results.append(dir+'/'+file)

    return results
  • 调用

print(read_dir(os.getcwd()))

['E:\\pythonProject\\pythonetl\\learning/learning_os.py', 'E:\\pythonProject\\pythonetl\\learning/learning_time.py', 'E:\\pythonProject\\pythonetl\\learning/learning_unittest.py', 'E:\\pythonProject\\pythonetl\\learning/learn_logging.py', 'E:\\pythonProject\\pythonetl\\learning/log_t1.py', 'E:\\pythonProject\\pythonetl\\learning/mycode.py']

当前路径E:\pythonProject\pythonetl\learning\learning_os.py,在learning_os.py中执行以下代码

os.getcwd()

print('getcwd',os.getcwd())

getcwd E:\pythonProject\pythonetl\learning

os.path.dirname(os.getcwd())

print('dirname',os.path.dirname(os.getcwd()))

dirname E:\pythonProject\pythonetl

os.path.dirname() 和 os.path.basename()

stra = ['E:\pythonProject\pythonetl']
for i in stra:
    print(os.path.dirname(i))
    print(os.path.basename(i))

E:\pythonProject
pythonetl

OS模块 — 实战版

  • 在until文件夹下创建filr_until.py文件
import os

def get_dir_files_list(path="./",recursive=False):
    # 判断文件夹下面,有哪些文件
    # :param path:被判断的文件夹的路径,默认当前路径
    # :param recursive:是否递归读取,默认不递归
    # :return:1ist对象,list里面存储的是文件的路径

    #os.listdir这个API返回的是你给定的path下面有哪些`文件和文件夹`、
    dir_names = os.listdir(path)
    # print('dir_names',dir_names)
    # if not dir_names:
    #     return os.path.basename(path)
    files =[]
    #定义一个list,用来记录文件
    for dir_name in dir_names:
        absolute_path = f"{path}/{dir_name}"
        if not os.path.isdir(absolute_path):
            # print('not a dir')
            #如果进来这个if,表明这个是:文件
            files.append(absolute_path)
        else:
            # print('is a dir')
            #表明是文件夹
            if recursive:
                #如果recursive是True,表明要进到文件夹里面继续找文件
                files += get_dir_files_list(absolute_path,recursive)
    return files

单元测试

  • test文件夹下的test_file_until.py文件
    在这里插入图片描述
import os.path
from unittest import TestCase
from util.file_util import get_dir_files_list


class TestFileUtil(TestCase):
    # 确定手动创建的测试目录的绝对路径
    def setUp(self) -> None: # 测试前需要提前执行的代码  例如连接数据库
        self.project_root_path = os.path.dirname(os.getcwd())
        print('解耦合获得路径:',self.project_root_path)
        pass

    def test_myfunc(self): # 要以test开头运行
        # 测试get_dir_files_list 函数
        # 该以哪一个作为我们的测试目录
        # 解耦合  ---
        '''
        请在工程根目录的test文件夹内建立:
        test_dir /
            inner1 /
                iner2 /
                    innner3/
                    5
                3
                4
            1
            2
        的目录结构用于进行此方法的单元测试
        不递归结果应该是1和2
        递归结果应该是1, 2, 3, 4, 5
        '''

        # 测试没有开启递归调用的代码
        result1 = get_dir_files_list(
            path = self.project_root_path + '/' + 'test_dir',
            recursive=False
        )

        predicted_result= ['1', '2']
        # self.assertEqual(results, predicted_result)
        result_1 = []
        for p in predicted_result:
            result_1.append(self.project_root_path + '/' + 'test_dir'+'/'+p)

        # 排除顺序对结果的影响
        result1.sort()
        result_1.sort()
        # 这里断言 函数获得的结果和预期的结果路径是一致的
        self.assertEqual(result1, result_1)


        # 测试开启递归调用的代码  不包括inner3这种情况
        result2 = get_dir_files_list(
            path = self.project_root_path + '/' + 'test_dir',
            recursive=True
        )
        predicted_result = ['1', '2','inner1/3','inner1/4','inner1/inner2/5',]
        # 若是  'inner1/4','inner1/3'  则会出现错误   因此 我们要加上一道保险  调整顺序
        # 使用sort()函数  没有返回值
        result_2 = []
        for p in predicted_result:
            result_2.append(self.project_root_path + '/' + 'test_dir'+'/'+p)

        result2.sort()
        result_2.sort()
        self.assertEqual(result2, result_2)


        # 测试开启递归调用的代码  测试空文件夹  针对 inner3这种情况
        '''
        实际上输出  不应该出现  'E:\\pythonProject\\pythonetl/test_dir/inner1/inner2/inner3'这种情况
        因为我们遍历的是可以用的文件   而非目录     所以想办法排除目录
        '''
        result3 = get_dir_files_list(
            path = self.project_root_path + '/' + 'test_dir',
            recursive=True
        )
        predicted_result = ['1', '2','inner1/3','inner1/4','inner1/inner2/5','inner1/inner2/inner3'] #
        # 若是  'inner1/4','inner1/3'  则会出现错误   因此 我们要加上一道保险  调整顺序
        # 使用sort()函数  没有返回值
        result_3 = []
        for p in predicted_result:
            result_3.append(self.project_root_path + '/' + 'test_dir'+'/'+p)
            #
            if os.path.isdir(result_3[-1]):
                if not os.listdir(result_3[-1]):
                    result_3.pop(-1)

        result3.sort()
        result_3.sort()
        self.assertEqual(result3, result_3)

    def tearDown(self)-> None: # 收尾工作
        pass
解耦合

在软件开发中,解耦合(Decoupling)是指减少或去除系统中各组件之间的相互依赖关系,以提高系统的灵活性和可维护性。

解耦合的目标是创建松散耦合的系统,其中每个组件或模块都可以独立于其他组件进行开发、测试和维护。

例如:

我的一个系统的文件路径是绝对路径, 若是我将该系统给另一个人,他会因为文件夹是否存在的问题而出现报错的风险,因此我们要做解耦合的措施

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【软件工程】软件开发模型

三、瀑布模型 四、几种软件开发模型的主要特点 题目 判断题 选择题 小结

1233333333333

📢博客主页:https://blog.csdn.net/2301_779549673 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! 📢本文由 JohnKi 原创,首发于 CSDN🙉 📢未来很长&#…

【leetcode详解】爬楼梯:DP入门典例(附DP通用思路 同类进阶练习)

实战总结&#xff1a; vector常用方法&#xff1a; 创建一个长为n的vector&#xff0c;并将所有元素初始化为某一定值x vector<int> vec(len, x) 代码执行过程中将所有元素更新为某一值x fill(vec.begin(), vec.end(), x) // 更多实战方法欢迎参考文章&#xff1a;…

halcon 自定义距离10的一阶导数幅图,摆脱sobel的3掩码困境

一&#xff0c;为什么要摆脱3的掩码 在处理图像的过程中&#xff0c;会用到平滑算子&#xff0c;很容易破坏边际&#xff0c;所谓的一阶导数sobel只计算掩码为3的差分&#xff0c;在幅度图分割中&#xff0c;往往是很难把握的。 举个例子-现在图像头平滑好了&#xff0c;缺陷…

在亚马逊云科技上利用Graviton4代芯片构建高性能Java应用(上篇)

简介 在AI迅猛发展的时代&#xff0c;芯片算力对于模型性能起到了至关重要的作用。一款能够同时兼具高性能和低成本的芯片&#xff0c;能够帮助开发者快速构建性能稳定的生成式AI应用&#xff0c;同时降低开发成本。今天小李哥将介绍亚马逊推出的4代高性能计算处理器Gravition…

使用vscode上传git远程仓库流程(Gitee)

目录 参考附件 git远程仓库上传流程 1&#xff0c;先将文件夹用VScode打开 2&#xff0c;第一次进入要初始化一下仓库 3&#xff0c;通过这个&#xff08;.gitignore&#xff09;可以把一些不重要的文件不显示 注&#xff1a;&#xff08;.gitignore中&#xff09;可屏蔽…

如何将代理IP设置为ISP:详细指南

在当今互联网时代&#xff0c;代理IP已经成为许多用户保护隐私和提升网络体验的重要工具。而ISP&#xff08;Internet Service Provider&#xff09;的代理IP更是因为其高质量和稳定性备受青睐。本文将详细介绍如何将代理IP设置为ISP&#xff0c;让你在网络世界中享受更优质的上…

RISC-V (十一)软件定时器

主要的思想&#xff1a;硬件定时器是由硬件的定时器设备触发的。软件定时器在硬件定时器的基础上由软件控制实现多个定时器的效果。主要的思路是在trap_handler函数中加入软件代码&#xff0c;使其在设定的时间点 去执行想要执行的功能函数。 定时器的分类 硬件定时器&#xf…

计算机网络(二) —— 网络编程套接字

目录 一&#xff0c;认识端口号 1.1 背景 1.2 端口号是什么 1.3 三个问题 二&#xff0c;认识Tcp协议和Udp协议 三&#xff0c;网络字节序 四&#xff0c;socket编程接口 4.1 socket常见API 4.2 sockaddr结构 一&#xff0c;认识端口号 1.1 背景 问题&#xff1a;在进…

网络安全运维培训一般多少钱

在当今数字化时代&#xff0c;网络安全已成为企业和个人关注的焦点。而网络安全运维作为保障网络安全的重要环节&#xff0c;其专业人才的需求也日益增长。许多人都对网络安全运维培训感兴趣&#xff0c;那么&#xff0c;网络安全运维培训一般多少钱呢? 一、影响网络安全运维培…

算法训练营——day4螺旋矩阵

1 螺旋矩阵II-力扣59&#xff08;中等&#xff09; 1.1 题目&#xff1a;螺旋矩阵II 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&…

算法学习:滑动窗口

题目 滑动窗口 滑动窗口的题目在解决统计连续带特殊要求的元素串问题时作用巨大。逃离仅仅只是套路学习的黑洞&#xff0c;我认为这种方法在无序的统计中&#xff0c;找到了有序的切入点。初看题目时&#xff0c;可以想到的统计方法有很多&#xff0c;但实现在计算机上则必须有…

贝锐蒲公英远程视频监控方案:4G入网无需公网IP,跨品牌统一管理

在部署视频监控并实现集中监看时&#xff0c;常常会遇到各种挑战。比如&#xff1a;部分监控点位布线困难、无法接入有线宽带&#xff0c;或是没有固定公网IP&#xff0c;难以实现远程集中监看&#xff1b;已有网络质量差&#xff0c;传输延迟大、丢包率高&#xff0c;远程实时…

【王树森】BERT:预训练Transformer模型(个人向笔记)

前言 BERT&#xff1a;Bidirectional Encoder Representations from TransformerBERT是用来预训练Transformer模型的encoder的本节课只讲述主要思想BERT用两个主要思想来训练Transformer的encoder网络&#xff1a;①随机遮挡单词&#xff0c;让encoder根据上下文来预测被遮挡的…

C语言蓝桥杯

一、语言基础 竞赛常用库函数 最值查询 min_element和max_element在vector(迭代器的使用) nth_element函数的使用 例题lanqiao OJ 497成绩分析 第一种用min_element和max_element函数的写法 第二种用min和max的写法 二分查找 二分查找只能对数组操作 binary_search函数&…

win12R2安装.NET Framework 3.5

一丶安装原因 因此插件的缺失, 有些软件或系统不支持安装. 二丶安装步骤 1丶下载.NET Framework 3.5 点击插件下载, 提取码: 1995, 下载完成之后解压到想要安装的位置上. 2丶打开 服务器管理器 3丶点击: 管理 -> 添加角色和功能 4丶点击下一步到服务器角色, 选择web服…

Android应用开发项目式教程——序

Android技术 Android是重要的客户端技术&#xff0c;因其开源开放的特点&#xff0c;Android在其初期就迅速成长为智能手机的主流操作系统&#xff0c;近年来更进一步成为智能电视、智能车载终端等智能设备的主流操作系统&#xff0c;其活跃设备数量已经超过30亿台&#xff0c…

通用内存快照裁剪压缩库Tailor介绍及源码分析(一)

背景 我们知道内存快照是治理 OOM 问题及其他类型的内存问题的重要数据源&#xff0c;内存快照中保存了进程虚拟机的完整的堆内存数据&#xff0c;很多时候也是调查其他类型异常的重要参考。但是dump出来的堆转储文件.hprof往往很大&#xff0c;以 LargeHeap 应用为例&#xf…

吐血整理 ChatGPT 3.5/4.0 新手使用手册~ 【2024.09.04 更新】

以前我也是通过官网使用&#xff0c;但是经常被封号&#xff0c;就非常不方便&#xff0c;后来有朋友推荐国内工具&#xff0c;用了一阵之后&#xff0c;发现&#xff1a;稳定方便&#xff0c;用着也挺好的。 最新的 GPT-4o、4o mini&#xff0c;可搭配使用~ 1、 最新模型科普&…

XGBoost算法-上

简单解释一下xgboost这个模型 xg是一个非常强大&#xff0c;非常受欢迎的机器学习模型&#xff0c;其中最大的特色就是boosting&#xff08;改进、推进&#xff09;&#xff0c;怎么改进呢&#xff1f;就是xgboost这个算法&#xff0c;它会先建立一颗简单的决策树&#xff0c;…