解析hosts.txt存储类信息遇AttributeError,求存储与读取优化方案
问题原因与解决办法
错误根源
你遇到的AttributeError是因为存储方式错误:代码里把split(',')得到的列表直接添加到了hosts列表中,而不是创建dest类的实例。所以hosts[0]是一个普通列表(比如['127.0.0.1', 'localhost']),自然没有.ip属性。
修正代码
把添加元素的逻辑改成创建dest实例再存入列表,同时优化文件读取的写法:
hosts = [] class dest: def __init__(self, ip, desc): self.ip = ip self.desc = desc def __str__(self): return f"{self.ip} ({self.desc})" # 读取文件并填充列表 with open('hosts.txt','r') as f: for line in f: # 直接遍历文件对象更简洁,替代while readline line = line.strip() if not line or line.startswith("#"): continue # 跳过空行和注释行 parts = line.split(',') # 简单处理格式错误,避免索引越界 if len(parts) >= 2: ip = parts[0].strip() desc = parts[1].strip() hosts.append(dest(ip, desc)) # 现在可以正常访问属性 print(hosts[0].ip) print(hosts[0].desc)
注意:with语句会自动关闭文件,原代码里的f.close()是多余的,直接删掉即可。
更优实现方式
1. 用dataclasses简化类定义
Python 3.7+的dataclasses可以自动生成__init__、__str__等方法,大幅简化类代码:
from dataclasses import dataclass @dataclass class Dest: # 类名遵循PEP8大驼峰规范 ip: str desc: str
这个类和你原来的dest功能完全一致,代码更简洁规范。
2. 健壮的读取与处理逻辑
把读取逻辑封装成生成器,分离数据读取和实例创建,同时处理格式错误的行:
from dataclasses import dataclass import os @dataclass class Dest: ip: str desc: str def read_hosts(file_path): with open(file_path, 'r') as f: for line_num, line in enumerate(f, 1): line = line.strip() if not line or line.startswith("#"): continue parts = line.split(',') if len(parts) < 2: print(f"警告:第{line_num}行格式错误,已跳过:{line}") continue yield Dest(parts[0].strip(), parts[1].strip()) # 生成hosts列表 hosts = list(read_hosts('hosts.txt')) # 遍历执行ping操作(以Linux系统为例) for host in hosts: print(f"测试 {host.desc} ({host.ip})...") # 静默执行ping,判断返回值 result = os.system(f"ping -c 2 {host.ip} > /dev/null 2>&1") print(f"{host.ip} {'可达' if result == 0 else '不可达'}\n")
这种方式代码复用性更强,还能避免因格式错误导致程序崩溃。
3. 命名规范建议
- 类名使用大驼峰(如
Dest),变量名用小蛇形,符合Python的PEP8编码规范,提升代码可读性。
内容的提问来源于stack exchange,提问作者Gauffke
相关产品推荐
相关产品推荐

