我有一组 python 文件,它们组成了一个程序,用于保存信息花絮并通过标签关联搜索它们。我让该程序适用于许多版本,但最近我做了一个我认为是导致程序失控的微小更改。 ENTRY 对象是数据存储的基础 - 它保存唯一的 ID 号、昵称、值和标签列表。
class ENTRY:
def __init__(self, idNum, nickName, value, tagList):
self.idNum = idNum
self.nickName = nickName
self.value = value
self.tagList = tagList
我意识到,当要求在其他文件中输入时,我将“nickName”属性互换地称为“name”,因此我决定查找所有提到的“nickName”并将其替换为“name”,以使代码更易于理解。我在 ENTRY.py 文件以及程序中所有关联的 python 文件中执行了此操作。我什至对它们进行了校对,以确保更改不会干扰任何区分大小写的函数调用或任何其他内容。
问题:现在,当我运行程序时,出现属性错误:
Traceback (most recent call last):
File "/Memory/TagMem.py", line 210, in <module>
main()
File "/Memory/TagMem.py", line 207, in main
dispatch(userChoice)
File "/Memory/TagMem.py", line 171, in dispatch
nameList('todo')
File "/Memory/TagMem.py", line 103, in nameList
memory.searchListNames(queryList)
File "/Memory/Memory.py", line 96, in searchListNames
each.printName()
File "/Memory/ENTRY.py", line 49, in printName
print("({}) {}".format(self.idNum, self.name))
AttributeError: 'ENTRY' object has no attribute 'name'
但是在查找和替换之后,ENTRY 对象肯定有一个属性“name”:
class ENTRY:
def __init__(self, idNum, name, value, tagList):
self.idNum = idNum
self.name = name
self.value = value
self.tagList = tagList
有谁知道当属性在类构造函数中非常明确地定义时我会收到属性错误的原因吗?
有关完整类代码的更完整信息,请参阅 github 存储库:https://github.com/kylelambert101/TagMem
以及导致崩溃的更改的具体提交: https://github.com/kylelambert101/TagMem/commit/68987f2e6ed98012f36ec5230b3dac6f09373489
谢谢!
我知道我错在哪里了!我的程序与一个名为
myMemory.dat
的文件关联,该文件存储 Memory
对象的腌制版本,并在程序每次运行时加载和保存。 Memory
对象本质上是要查询的 ENTRY
的列表。当我更新所有代码以使用名称 name
而不是 nickname
时,我已经在 ENTRY
中保存了数百个 myMemory.dat
对象 - 每个对象都是旧 ENTRY
对象的实例,并带有nickName
属性而不是 name
属性。当我调用尝试访问 ENTRY
对象的 name
属性的函数时,程序抛出错误,因为相关的 ENTRY
对象没有该属性。
修复:我循环遍历存储在
Memory
中的 myMemory.dat
对象,并将所有信息复制到新 ENTRY
对象中的新 Memory
中。我将新的 Memory
保存到 myMemory.dat
,程序运行得像新的一样!
检查类的
__init__()
方法中属性定义的顺序。想象一下,您有一个具有私有属性 Foo
的类 _bar
。进一步想象类 Foo
有一个操作属性 foo_bar()
的方法 _bar
。如果在定义 foo_bar()
属性之前,在 __init__()
方法中调用 _bar
方法,你会得到一个 AttributeError
。
Python 示例:
class Foo:
_bar: str
def __init__(self):
# Uncomment the next line to fix the issue
# self._bar = "success"
self.foo_bar() # Calling foo_bar() before defining _bar will result in an AttributeError
# Comment the next line to fix the issue
self._bar = "error"
def foo_bar(self):
print(self._bar)
obj = Foo()
在此示例中,如果取消注释行
self._bar = "success"
并注释 self._bar = "error"
行,代码将运行而不会出现错误。但是,如果保持原样,您将得到一个 AttributeError
,因为在类中定义属性 foo_bar()
之前调用方法 self._bar
。