引言
文章目录
一、需求:
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_search
和search_term
变量的值。
- 调用 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
循环来遍历所有子目录,并为每个子目录创建一个线程。 - 循环的
break
和continue
语句可以用来控制循环的流程。
4.5 代码组织和可读性
- 代码通过合理的函数和类定义,实现了文件搜索的功能。
- 代码中的注释有助于提高代码的可读性,使其他开发者能够理解代码的功能和目的。