Python对象存在Csapat属性却无法访问,触发AttributeError异常
问题描述
尝试读取文件并转换为SQL表,但访问File对象的Csapat属性时触发错误:
AttributeError: 'File' object has no attribute 'Csapat'
代码实现
File类定义
class File: columns = list(firstLine("focivb.txt")) def __init__(self, *args): index = 0 for arg in args: try: arg = int(arg) except: arg = str(arg) if isinstance(arg, int): setattr(self, self.columns[index][0], arg) self.columns[index][1] = "int" index += 1 if isinstance(arg, str): setattr(self, self.columns[index][0], arg) self.columns[index][1] = "string" index += 1
读取文件函数
def readFile(file): with open(file, "r", encoding="utf-8") as read: content = read.readlines() isFirstLine = True for line in content: obj = line.split("\t") if isFirstLine: isFirstLine = False continue for i in range(len(obj)): yield File(*obj)
执行代码与firstLine函数
objs = list(readFile("focivb.txt")) for i in objs: print(getattr(i, "Csapat")) def firstLine(file): with open(file, "r", encoding="utf-8") as read: content = read.readlines() for i in range(len(content[0].split('\t'))): yield [content[0].split('\t')[i], 0]
问题原因与修复方案
核心问题1:readFile函数重复创建对象
readFile里的内层循环for i in range(len(obj)): yield File(*obj)完全冗余,会对同一行数据重复创建len(obj)次File对象,不仅浪费资源,还可能导致属性映射异常。直接去掉内层循环,每行仅创建一个对象即可。
核心问题2:类属性columns被实例篡改
File.columns是类级属性,所有实例共享,初始化时修改self.columns[index][1]会导致后续实例的列类型被之前的实例覆盖,引发属性匹配错误。应该改用实例属性存储当前实例的列类型,或者只读取类属性的列名而不修改它。
核心问题3:参数处理易引发越界错误
初始化时未限制index范围,若输入参数数量多于列数,会触发索引越界。同时字符串转换逻辑可简化,还需去除字符串两端的空白(如换行符)避免属性值异常。
修复后的完整代码
工具函数与File类
def firstLine(file): with open(file, "r", encoding="utf-8") as read: # 读取首行并去除换行符,避免列名带无效字符 first_line = read.readline().strip() for col_name in first_line.split('\t'): yield [col_name, 0] class File: # 类属性仅存储初始列信息,不修改 _columns = list(firstLine("focivb.txt")) def __init__(self, *args): index = 0 # 取列数和参数数的最小值,防止索引越界 max_process = min(len(self._columns), len(args)) # 用实例属性存储当前实例的列类型 self._col_types = {} for arg in args[:max_process]: try: value = int(arg) col_type = "int" except (ValueError, TypeError): # 去除字符串两端的空白和换行符 value = str(arg).strip() col_type = "string" # 为实例设置属性 setattr(self, self._columns[index][0], value) self._col_types[self._columns[index][0]] = col_type index += 1
读取文件函数
def readFile(file): with open(file, "r", encoding="utf-8") as read: content = read.readlines() is_first_line = True for line in content: line = line.strip() if not line: continue # 跳过空行 obj = line.split("\t") if is_first_line: is_first_line = False continue # 每行只创建一个File对象 yield File(*obj)
执行代码
objs = list(readFile("focivb.txt")) for item in objs: # 先检查属性是否存在,避免报错 if hasattr(item, "Csapat"): print(getattr(item, "Csapat")) else: print(f"对象缺少Csapat属性,当前属性:{item.__dict__}")
内容的提问来源于stack exchange,提问作者Kariko
相关产品推荐
相关产品推荐

