Python解析YAML遇空port键触发KeyError,需优化处理方案
从多个YAML文件提取数据到CSV时处理空port键报错问题
我有大量结构相似但数据不同的YAML文件,需要从中提取指定数据写入单个CSV文件的对应列。但解析时遇到空的port键会触发「KeyError: 'port'」报错,示例YAML中第二个base块的port值为空,需求是遇到空键时不写入任何内容。
YAML文件示例
base: server: 10.100.80.47 port: 3306 namePrefix: well user: user1 password: kjj&%$ base: server: 10.100.80.48 port: namePrefix: done user: user2 password: fhfh#$%
当前Python代码
from asyncio.windows_events import NULL from queue import Empty import yaml import csv import glob yaml_file_names = glob.glob('./*.yaml') rows_to_write = [] for i, each_yaml_file in enumerate(yaml_file_names): print("Processing file {} of {} file name: {}".format( i+1, len(yaml_file_names),each_yaml_file)) with open(each_yaml_file) as file: data = yaml.safe_load(file) for v in data: if "port" in v == "": data['base']['port'] = "" rows_to_write.append([data['base']['server'],data['base']['port'],data['server']['host'],data['server']['contex']]) with open('output_csv_file.csv', 'w', newline='') as out: csv_writer = csv.writer(out) csv_writer.writerow(["server","port","hostname", "contextPath"]) csv_writer.writerows(rows_to_write) print("Output file output_csv_file.csv created")
问题分析与修正方案
你的代码存在多处逻辑错误,导致无法正确处理多文件和空port的情况,以下是修正后的代码及关键说明:
修正后的代码
import yaml import csv import glob yaml_file_names = glob.glob('./*.yaml') rows_to_write = [] for i, each_yaml_file in enumerate(yaml_file_names): print(f"Processing file {i+1} of {len(yaml_file_names)} file name: {each_yaml_file}") with open(each_yaml_file) as file: data = yaml.safe_load(file) # 用get方法安全获取值,避免KeyError,空值时返回空字符串 server = data.get('base', {}).get('server', '') port = data.get('base', {}).get('port', '') # 注意:原代码中的data['server']在示例YAML中不存在,这里用get方法容错,同时修正contex为context hostname = data.get('server', {}).get('host', '') context_path = data.get('server', {}).get('context', '') rows_to_write.append([server, port, hostname, context_path]) with open('output_csv_file.csv', 'w', newline='', encoding='utf-8') as out: csv_writer = csv.writer(out) csv_writer.writerow(["server", "port", "hostname", "contextPath"]) csv_writer.writerows(rows_to_write) print("Output file output_csv_file.csv created")
关键修正点
- 多文件处理逻辑:将数据提取和添加到
rows_to_write的代码放到YAML文件循环内部,确保每个文件的数据都被处理,而不是只保留最后一个文件的内容 - 安全获取字典值:使用字典的
get()方法,格式为dict.get(key, 默认值),即使键不存在或者值为空,也会返回指定的默认值(这里用空字符串),彻底避免KeyError - 键名错误修正:原代码中
data['server']['contex']存在拼写错误,修正为context,同时用get()方法容错,避免因YAML中无server节点报错 - 代码简化:删除无用的导入(
NULL、Empty),使用f-string简化打印语句,添加编码参数确保CSV文件兼容性
内容的提问来源于stack exchange,提问作者Paulo
相关产品推荐
相关产品推荐

