You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 18:55:13