AttributeError,声称显然存在的属性不存在。我为什么要这样做? (子类问题)

时间:2018-05-02 14:34:30

标签: python

在我一直在做的大型程序中,我遇到了一个属性错误:

line 154, in __ExtINT
    DebugVar=Self.__Preset # Originally, I had Self.__Preset directly in an if statement. I added this line and put DebugVar in the if statement, so I could be sure what was causing the error.
AttributeError: '__Readitem' object has no attribute '_ReadItem__Preset'

我确信它是在__init__函数中设置的,并花了一段时间试图弄清楚为什么我会收到此错误。当我发现python使用字典存储其所有变量时,我将print(Self.__dict__)放在导致错误的行之前,这样我就可以看到做了的属性。我很惊讶地看到字典中的, '_Readitem__Preset': True}。为什么说它不存在,那么在错误中呢?

我尝试了DebugVar=Self.__dict__['_Readitem__Preset']而不是DebugVar=Self.__Preset,并得到了:

line 154, in __ExtINT
    DebugVar=Self.__dict__['_Readitem__Preset']
KeyError: '_Readitem__Preset'

然后我尝试在self.__Preset=False后直接放__init__,这样我就可以确定它确实存在了。

值得一提的是,在我尝试从变量中手动提取值之前,显示了2个词典,这意味着最初的代码一次。更改代码后,只显示了一个字典。

有没有人自己遇到过这个问题,或者知道为什么会这样?

1 个答案:

答案 0 :(得分:1)

那很痛苦。

我已经设法弄清楚为什么我收到错误并修复我的代码。这是一个描述我如何得到错误以及我如何克服它以防任何人好奇或自己得到这个错误:

在我的代码中,我有一个基本上属于类的类。它存储属性,例如它是预定义的还是用户定义的,是否包含任何子类别,它可能具有的任何子类别等。这些子类别是包含该类的更多实例的列表。然后我不得不创建它的另一个版本,它在初始化时写入文件。如果我像以前一样这样做,那么它会将应该只写入文件一次的数据写入文件多次。我决定创建一个“子类”,它的工作方式与它的主类略有不同。这是一些简单的代码,显示了我试图实现的结构:

class Main():
    class __Sub():
        def __init__(self,file,dat):
            if isinstance(dat,tuple):
                self.__trace=()
                if False in (isinstance(i,int)for i in dat):self.__trace+=tuple((Main.__Sub(file,i),)for i in dat)
                else:
                    self.__trace=dat
                    file.write(bytes(dat))
            else:
                self.__trace=(dat,)
                file.write(bytes([dat]))
    def __init__(self,file,dat):
        File=open(file,"wb")
        self.__trace=()
        self.__trace+=tuple((Main.__Sub(File,i),)for i in dat)
        File.close()
Main(input("Enter file name: "),(4,8,((32,71),255)))

正如我在问题中所说,python将其变量存储在字典中,您可以使用.__dict__检查对象的属性。如果这样做,您将看到每个属性都将其类的名称作为前缀。如果您因某种原因尝试运行上面的代码,它会崩溃,因为它会尝试使用错误的前缀来查找属性。

我的解决方法是删除子类,并对我的代码执行此操作:

class Main():
    def __init__(self,file,dat):
        if "BadPractice" in globals():
            if isinstance(dat,tuple):
                self.__trace=()
                if False in (isinstance(i,int)for i in dat):self.__trace+=tuple((Main(file,i),)for i in dat)
                else:
                    self.__trace=dat
                    file.write(bytes(dat))
            else:
                self.__trace=(dat,)
                file.write(bytes([dat]))
        else:
            global BadPractice
            BadPractice=None
            self.__trace=()
            self.__trace+=tuple((Main(file,i),)for i in dat)
            file.close()
Main(open(input("Enter file name: "),"wb"),(4,8,((32,71,),255,),),)

这可能不是最好的方法,但它修复了错误。