【python学习】多线程文件名称查找:使用面向对象编程方式实现对某一文件夹启动10个线程查找文件包含abc三个字符的文件名,并显示该文件所在的路径

引言

一、需求:

1.1 使用面向对象编程方式

1.2 实现对某一文件夹启动10个线程查找文件包含abc三个字符的文件名

1.3 显示该文件所在的路径

二、代码(加注释

import os
import threading
# 定义一个名为 FileSearch 的类
class FileSearch:
    def __init__(self, directory, search_term):
        # 初始化类属性
        self.directory = directory  # 设置搜索的目录
        self.search_term = search_term  # 设置搜索词
        self.search_files = []  # 用于存储找到的文件路径
    def search(self, start_path):
        # 定义一个搜索方法,用于在给定的路径下查找包含搜索词的文件
        for root, _, files in os.walk(start_path):
            for file in files:
                # 如果搜索词在文件名中,则添加文件路径到搜索文件列表中
                if self.search_term in file:
                    self.search_files.append(os.path.join(root, file))
    def run(self):
        # 定义一个运行方法,用于启动多线程搜索
        directories = [os.path.join(self.directory, d) for d in os.listdir(self.directory)
                       if os.path.isdir(os.path.join(self.directory, d))]
        threads = []
        # 遍历所有子目录,并为每个子目录创建一个线程
        for sub_dir in directories:
            thread = threading.Thread(target=self.search, args=(sub_dir,))
            threads.append(thread)
            thread.start()
            # 如果线程数量达到10,则等待第一个线程完成
            if len(threads) >= 10:
                threads[0].join()
                threads.pop(0)
        # 等待所有线程完成
        for thread in threads:
            thread.join()
        # 返回找到的文件列表
        return self.search_files
if __name__ == '__main__':
    # 设置要搜索的目录和搜索词
    directory_to_search = "D:\\test"
    search_term = 'abc'
    # 创建 FileSearch 类的实例
    file_searcher = FileSearch(directory_to_search, search_term)
    # 调用 run 方法进行搜索
    found_files = file_searcher.run()
    # 遍历找到的文件列表,并打印每个文件的路径
    for file_path in found_files:
        print(file_path)

这段代码的主要功能是在指定的目录中搜索包含特定搜索词的文件,并使用多线程来加速搜索过程

三、详细解释:

3.1 导入模块

```python
import os
import threading
```
这两行代码导入了`os`和`threading`模块。`os`模块用于与操作系统交互,比如遍历文件系统。`threading`模块用于创建和管理线程

3.2 定义FileSearch

```python
class FileSearch:
```
这是一个类定义,`FileSearch`用于封装文件搜索功能

3.3 __init__方法

        def __init__(self, directory, search_term):
            self.directory = directory
            self.search_term = search_term
            self.search_files = []

这是FileSearch类的构造函数,它初始化三个实例变量:directory是要搜索的目录,search_term是要搜索的字符串,search_files是一个空列表,用于存储找到的文件路径

3.4 search方法

        def search(self, start_path):
            for root, _, files in os.walk(start_path):
                for file in files:
                    if self.search_term in file:
                        self.search_files.append(os.path.join(root, file))

search方法定义了搜索逻辑。它接收一个start_path参数,表示搜索的起始路径
使用os.walk()函数遍历给定路径下的所有文件和子目录,如果文件名包含search_term,则将文件的完整路径添加到search_files

3.5run 方法

    def run(self):
        # 定义一个运行方法,用于启动多线程搜索
        directories = [os.path.join(self.directory, d) for d in os.listdir(self.directory)
                       if os.path.isdir(os.path.join(self.directory, d))]
        threads = []

        # 遍历所有子目录,并为每个子目录创建一个线程
        for sub_dir in directories:
            thread = threading.Thread(target=self.search, args=(sub_dir,))
            threads.append(thread)
            thread.start()

            # 如果线程数量达到10,则等待第一个线程完成
            if len(threads) >= 10:
                threads[0].join()
                threads.pop(0)

        # 等待所有线程完成
        for thread in threads:
            thread.join()

        # 返回找到的文件列表
        return self.search_files

这段代码的作用是:

3.5.1 初始化

  • 使用列表推导式创建一个包含所有子目录的列表 directories
  • 创建一个空列表 threads 来存储线程对象。

3.5.2 多线程搜索

  • 遍历 directories 列表中的每个子目录。
  • 为每个子目录创建一个线程,线程的目标是调用 search 方法,并将当前子目录作为参数传递。
  • 如果线程数量达到10,则等待列表中的第一个线程完成,然后将其从列表中移除。

3.5.3 等待所有线程完成

  • 循环遍历 threads 列表,等待每个线程完成。

3.5.4 返回结果

  • 一旦所有线程完成,run 方法返回 search_files 列表,其中包含所有找到的文件路径。

3.5.5 run 方法的核心思想

  • 使用多线程来并行搜索多个子目录,从而提高搜索效率
  • 通过限制线程数量(在这个例子中是10),可以避免创建过多的线程,同时确保在搜索过程中始终有线程在运行
  • 当线程数量超过10时,代码会等待第一个线程完成,然后继续创建新的线程,以保持10个线程的活跃状态

3.6 调用

1.Python中,if __name__ == '__main__': 是一个常见的代码块,用于确保代码只在直接运行脚本时执行,而不是在导入模块时执行
2.这个条件检查可以防止模块中的代码在导入时被无谓地执行
3.if __name__ == '__main__': 块是脚本的入口点

if __name__ == '__main__':
    # 设置要搜索的目录和搜索词
    directory_to_search = "D:\\test"
    search_term = 'abc'

    # 创建 FileSearch 类的实例
    file_searcher = FileSearch(directory_to_search, search_term)

    # 调用 run 方法进行搜索
    found_files = file_searcher.run()

    # 遍历找到的文件列表,并打印每个文件的路径
    for file_path in found_files:
        print(file_path)

3.6.1 设置要搜索的目录和搜索词

directory_to_search = "D:\\test"
search_term = 'abc'

这两行代码设置了要搜索的目录路径和搜索词。directory_to_search 变量包含了文件夹的路径,而 search_term 变量包含了要搜索的字符串。

3.6.2 创建 FileSearch 类的实例

file_searcher = FileSearch(directory_to_search, search_term)

这一行代码创建了一个 FileSearch 类的实例。这个实例包含了对 FileSearch 类的引用,以及 directory_to_searchsearch_term 变量的值。

  1. 调用 run 方法进行搜索:
found_files = file_searcher.run()

这一行代码调用了 file_searcher 实例的 run 方法。这个方法会启动多线程搜索,并在所有线程完成后返回一个包含找到的文件路径的列表。

3.6.4 遍历找到的文件列表,并打印每个文件的路径

for file_path in found_files:
	print(file_path)

这个循环遍历 found_files 列表中的每个文件路径,并打印出来。

3.6.5 总结

if __name__ == '__main__': 块是脚本的入口点,它定义了如何设置搜索参数、创建 FileSearch 类的实例、调用 run 方法进行搜索,以及如何处理和显示搜索结果。这个代码块确保了脚本在直接运行时执行这些操作,而不是在导入模块时执行。

四、思考和总结

4.1 多线程编程

  • 代码中使用了 threading.Thread 类来创建和管理线程。
  • 通过多线程,可以同时对多个子目录进行搜索,从而提高搜索效率。
  • 线程数量的限制(在这个例子中是10)可以避免创建过多的线程,同时确保在搜索过程中始终有线程在运行。

4.2 文件系统操作

  • 代码使用了 os.walk() 函数来遍历文件系统中的目录和文件。
  • os.walk() 函数返回一个三元组列表,包含当前目录路径、子目录列表和文件列表。
  • 代码通过遍历这些三元组来查找包含搜索词的文件。

4.3 类和对象

  • 代码定义了一个名为 FileSearch 的类,用于封装文件搜索的功能。
  • 类中包含了一个构造函数 __init__,用于初始化类的属性。
  • 类中还包含了一个 search 方法和一个 run 方法,分别用于定义搜索逻辑和启动多线程搜索。
  • 通过创建类的实例,可以复用类的属性和方法。

4.4 条件语句和循环

  • 代码中使用了 if 语句来检查线程数量是否达到10,并决定是否等待第一个线程完成。
  • 代码中使用了 for 循环来遍历所有子目录,并为每个子目录创建一个线程。
  • 循环的 breakcontinue 语句可以用来控制循环的流程。

4.5 代码组织和可读性

  • 代码通过合理的函数和类定义,实现了文件搜索的功能。
  • 代码中的注释有助于提高代码的可读性,使其他开发者能够理解代码的功能和目的。
  • 35
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用线编程实现三个线程交替打印abc。下面是一个示例代码: ```python import threading class PrintABC: def __init__(self): self.current_letter = 'A' self.lock = threading.Lock() def print_a(self): for _ in range(10): with self.lock: while self.current_letter != 'A': self.lock.wait() print('A', end='') self.current_letter = 'B' self.lock.notify_all() def print_b(self): for _ in range(10): with self.lock: while self.current_letter != 'B': self.lock.wait() print('B', end='') self.current_letter = 'C' self.lock.notify_all() def print_c(self): for _ in range(10): with self.lock: while self.current_letter != 'C': self.lock.wait() print('C', end='') self.current_letter = 'A' self.lock.notify_all() def main(): printer = PrintABC() thread_a = threading.Thread(target=printer.print_a) thread_b = threading.Thread(target=printer.print_b) thread_c = threading.Thread(target=printer.print_c) thread_a.start() thread_b.start() thread_c.start() thread_a.join() thread_b.join() thread_c.join() if __name__ == '__main__': main() ``` 这个例子中,我们创建了一个 `PrintABC` 类,其中包含了三个方法 `print_a`、`print_b` 和 `print_c` 分别用于打印字母 'A'、'B' 和 'C'。在每个方法中,使用 `with self.lock` 来获取锁对象并进入临界区域。通过 `self.current_letter` 来确定当前应该打印的字母,并使用 `while self.current_letter != 'A'` 等待其他线程改变 `self.current_letter` 的值。当当前字母符合要求时,打印字母并切换到下一个字母,然后使用 `self.lock.notify_all()` 唤醒其他等待的线程。 在 `main` 方法中,我们创建了三个线程并分别启动它们,然后使用 `join` 方法等待所有线程执行完毕。运行这段代码时,你将会看到三个线程交替打印字母 'A'、'B' 和 'C',每个字母连续打印十次。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值