深入理解 Python 中的 `os.walk()`

2024-05-29 02:28
文章标签 python 深入 理解 walk os

本文主要是介绍深入理解 Python 中的 `os.walk()`,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在处理文件系统时,我们经常需要遍历目录结构以查找特定文件或执行某些操作。Python 提供了一个非常有用的函数 os.walk(),它可以帮助我们轻松地遍历目录树。本文将详细介绍 os.walk() 的使用,并提供一个实际的应用示例。

os.walk() 的基本用法

os.walk() 是一个生成器,它会递归地遍历目录树中的所有目录和文件。它的基本语法如下:

import osfor dirpath, dirnames, filenames in os.walk('your_directory'):print('Current Path:', dirpath)print('Directories:', dirnames)print('Files:', filenames)

参数说明

  • dirpath:当前遍历的目录路径。
  • dirnames:当前目录下的子目录列表。
  • filenames:当前目录下的文件列表。

示例

假设我们的目录结构如下:

example_dir/
│
├── subdir1/
│   ├── file1.txt
│   └── file2.txt
│
├── subdir2/
│   └── file3.txt
│
└── file4.txt

我们使用 os.walk() 来遍历这个目录:

import osfor dirpath, dirnames, filenames in os.walk('example_dir'):print('Current Path:', dirpath)print('Directories:', dirnames)print('Files:', filenames)

输出结果将如下所示:

Current Path: example_dir
Directories: ['subdir1', 'subdir2']
Files: ['file4.txt']Current Path: example_dir/subdir1
Directories: []
Files: ['file1.txt', 'file2.txt']Current Path: example_dir/subdir2
Directories: []
Files: ['file3.txt']

可以看到,os.walk() 递归地遍历了 example_dir 目录中的所有子目录和文件。

实际应用示例:同步文件到 MongoDB

我们通过一个实际的示例来展示 os.walk() 的应用。假设我们需要同步一个目录中的 PDF 和 XML 文件到 MongoDB,并且 XML 文件和对应的 PDF 文件在同一个目录中,但名称不一定相同。我们可以使用 os.walk() 来遍历目录,并找到每个 XML 文件对应的 PDF 文件。

完整代码示例

import logging
import os
import re
from logging import handlers
from datetime import datetime
import xml.etree.ElementTree as ET
from pymongo import MongoClient, errors
import gridfs# 用户输入部分
sync_file_path = ''
sync_mongo_url = ''
sync_mongo_username = ''
sync_mongo_password = ''
sync_mongo_db = ''
sync_mongo_collection = ''if sync_file_path == '':sync_file_path = r'D:\WG\202304'
if sync_mongo_db == '':sync_mongo_db = 'FMSQ'
if sync_mongo_collection == '':sync_mongo_collection = 'test'
if sync_mongo_url == '':sync_mongo_url = '192.168.0.234:27017'
if sync_mongo_username == '':sync_mongo_username = 'admin'
if sync_mongo_password == '':sync_mongo_password = '123456'# 日志文件配置
log_dir = f'./log/sync_pdf_xml_to_mongo_0001/{sync_mongo_db}-{sync_mongo_collection}'
if not os.path.exists(log_dir):os.makedirs(log_dir)class Logger(object):level_relations = {'debug': logging.DEBUG,'info': logging.INFO,'warning': logging.WARNING,'error': logging.ERROR,'crit': logging.CRITICAL}def __init__(self, filename, level='info', when='D', back_count=3,fmt='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'):self.logger = logging.getLogger(filename)format_str = logging.Formatter(fmt)self.logger.setLevel(self.level_relations.get(level))sh = logging.StreamHandler()sh.setFormatter(format_str)th = handlers.TimedRotatingFileHandler(filename=filename, when=when, backupCount=back_count, encoding='utf-8')th.setFormatter(format_str)self.logger.addHandler(sh)self.logger.addHandler(th)log_all_path = f'{log_dir}/sync_pdf_to_mongo_all.log'
log_error_path = f'{log_dir}/sync_pdf_to_mongo_error.log'
log = Logger(log_all_path, level='debug')
error_log = Logger(log_error_path, level='error')def find_pdf_file(xml_file_path, files):directory = os.path.dirname(xml_file_path)for file in files:if file.endswith(".PDF"):return os.path.join(directory, file)return Nonedef upload_files():log.logger.info(f"Sync directory path: {sync_file_path}")log.logger.info(f"MongoDB URL: {sync_mongo_url}")log.logger.info(f"MongoDB username: {sync_mongo_username}")log.logger.info(f"MongoDB password: {sync_mongo_password}")log.logger.info(f"MongoDB database: {sync_mongo_db}")log.logger.info(f"MongoDB collection: {sync_mongo_collection}")# MongoDB 连接client = MongoClient(f"mongodb://{sync_mongo_username}:{sync_mongo_password}@{sync_mongo_url}/?retryWrites=true&w=majority",serverSelectionTimeoutMS=5000)db = client[sync_mongo_db]fs = gridfs.GridFS(db)for root, dirs, files in os.walk(sync_file_path):for file in files:if file.endswith(".XML"):xml_file_path = os.path.join(root, file)pdf_file_path = find_pdf_file(xml_file_path, files)if not pdf_file_path:error_log.logger.error(f"PDF file not found for XML: {xml_file_path}")continuetry:tree = ET.parse(xml_file_path)root_element = tree.getroot()doc_number_match = re.search(r'docNumber="([\s\S]*?)"', ET.tostring(root_element, encoding='utf-8').decode('utf-8'))if not doc_number_match:error_log.logger.error(f"docNumber not found in XML: {xml_file_path}")continuedoc_number = doc_number_match.group(1)new_pdf_filename = f"{doc_number}.PDF"new_pdf_file_path = os.path.join(root, new_pdf_filename)os.rename(pdf_file_path, new_pdf_file_path)log.logger.info(f"Renamed {pdf_file_path} to {new_pdf_file_path}")query = {"filename": new_pdf_filename}log.logger.info(f"{new_pdf_filename} uploaded to MongoDB.")if fs.exists(query):log.logger.info(f"{new_pdf_filename} already exists in MongoDB.")else:with open(new_pdf_file_path, 'rb') as pdf_file:content = pdf_file.read()fs.put(content, filename=new_pdf_filename, upload_time=datetime.now())log.logger.info(f"{new_pdf_filename} uploaded to MongoDB.")except (errors.ServerSelectionTimeoutError, errors.AutoReconnect) as conn_error:error_log.logger.error(f"Error connecting to MongoDB while processing XML: {xml_file_path}: {conn_error}")except Exception as e:error_log.logger.error(f"Error processing XML file: {xml_file_path}: {e}")log.logger.info("All files processed.")upload_files()

在这个示例中,我们使用 os.walk() 递归地遍历指定目录中的所有文件和子目录,并对每个 XML 文件执行以下操作:

  1. 查找同目录中的 PDF 文件。
  2. 解析 XML 文件以提取 docNumber
  3. 重命名 PDF 文件,并将其上传到 MongoDB。

通过这种方式,我们能够有效地处理目录中的所有文件,并确保每个 XML 文件都有对应的 PDF 文件。

这篇关于深入理解 Python 中的 `os.walk()`的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1012377

相关文章

Python 字符串占位

在Python中,可以使用字符串的格式化方法来实现字符串的占位。常见的方法有百分号操作符 % 以及 str.format() 方法 百分号操作符 % name = "张三"age = 20message = "我叫%s,今年%d岁。" % (name, age)print(message) # 我叫张三,今年20岁。 str.format() 方法 name = "张三"age

回调的简单理解

之前一直不太明白回调的用法,现在简单的理解下 就按这张slidingmenu来说,主界面为Activity界面,而旁边的菜单为fragment界面。1.现在通过主界面的slidingmenu按钮来点开旁边的菜单功能并且选中”区县“选项(到这里就可以理解为A类调用B类里面的c方法)。2.通过触发“区县”的选项使得主界面跳转到“区县”相关的新闻列表界面中(到这里就可以理解为B类调用A类中的d方法

一道经典Python程序样例带你飞速掌握Python的字典和列表

Python中的列表(list)和字典(dict)是两种常用的数据结构,它们在数据组织和存储方面有很大的不同。 列表(List) 列表是Python中的一种有序集合,可以随时添加和删除其中的元素。列表中的元素可以是任何数据类型,包括数字、字符串、其他列表等。列表使用方括号[]表示,元素之间用逗号,分隔。 定义和使用 # 定义一个列表 fruits = ['apple', 'banana

Python应用开发——30天学习Streamlit Python包进行APP的构建(9)

st.area_chart 显示区域图。 这是围绕 st.altair_chart 的语法糖。主要区别在于该命令使用数据自身的列和指数来计算图表的 Altair 规格。因此,在许多 "只需绘制此图 "的情况下,该命令更易于使用,但可定制性较差。 如果 st.area_chart 无法正确猜测数据规格,请尝试使用 st.altair_chart 指定所需的图表。 Function signa

python实现最简单循环神经网络(RNNs)

Recurrent Neural Networks(RNNs) 的模型: 上图中红色部分是输入向量。文本、单词、数据都是输入,在网络里都以向量的形式进行表示。 绿色部分是隐藏向量。是加工处理过程。 蓝色部分是输出向量。 python代码表示如下: rnn = RNN()y = rnn.step(x) # x为输入向量,y为输出向量 RNNs神经网络由神经元组成, python

python 喷泉码

因为要完成毕业设计,毕业设计做的是数据分发与传输的东西。在网络中数据容易丢失,所以我用fountain code做所发送数据包的数据恢复。fountain code属于有限域编码的一部分,有很广泛的应用。 我们日常生活中使用的二维码,就用到foutain code做数据恢复。你遮住二维码的四分之一,用手机的相机也照样能识别。你遮住的四分之一就相当于丢失的数据包。 为了实现并理解foutain

python 点滴学

1 python 里面tuple是无法改变的 tuple = (1,),计算tuple里面只有一个元素,也要加上逗号 2  1 毕业论文改 2 leetcode第一题做出来

Python爬虫-贝壳新房

前言 本文是该专栏的第32篇,后面会持续分享python爬虫干货知识,记得关注。 本文以某房网为例,如下图所示,采集对应城市的新房房源数据。具体实现思路和详细逻辑,笔者将在正文结合完整代码进行详细介绍。接下来,跟着笔者直接往下看正文详细内容。(附带完整代码) 正文 地址:aHR0cHM6Ly93aC5mYW5nLmtlLmNvbS9sb3VwYW4v 目标:采集对应城市的

python 在pycharm下能导入外面的模块,到terminal下就不能导入

项目结构如下,在ic2ctw.py 中导入util,在pycharm下不报错,但是到terminal下运行报错  File "deal_data/ic2ctw.py", line 3, in <module>     import util 解决方案: 暂时方案:在终端下:export PYTHONPATH=/Users/fujingling/PycharmProjects/PSENe

如何理解redis是单线程的

写在文章开头 在面试时我们经常会问到这样一道题 你刚刚说redis是单线程的,那你能不能告诉我它是如何基于单个线程完成指令接收与连接接入的? 这时候我们经常会得到沉默,所以对于这道题,笔者会直接通过3.0.0源码分析的角度来剖析一下redis单线程的设计与实现。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ,是 CSDN的博客专家 ,也是开源