This code throws me an error due to the class. I get the error:
AttributeError: 'My_Data' object has no attribute 'Other'
The error is in the row My_Dictionary[row[0]].Other.append(row[3])
The problem certainly concerns the classes, because this code works correctly if: i use it without the Page1 class, but using only the My_Data class (without self in init). I've reduced and simplified the code as much as possible, removing useless but obvious parts for solving the question. Thank you
How can I fix? Thank you
class Page1(tk.Frame):
def __init__(self, master, other, **kw):
super().__init__(master, **kw)
self.configure(bg='white')
class My_Data():
def __init__(self, Name, Year, Other):
self.Name: str
self.Year: float
self.Other: list[int]
def function1(self):
My_Dictionary = {}
x = cursor.execute("sql")
for row in x.fetchall():
if row[0] not in My_Dictionary:
Data = My_Data(
Name=row[1],
Year=row[2],
Other=list())
My_Dictionary[row[0]] = info
My_Dictionary[row[0]].Other.append(row[3])
print(My_Dictionary)
UPDATE My previous code that worked fine, if: i use it without the Page1 class, but using only the My_Data class (without self in init):
class My_Data:
Name: str
Year: float
Other: list[int]
def function1():
My_Dictionary = {}
x = cursor_test.execute("sql")
for row in x.fetchall():
if row[0] not in My_Dictionary:
info = My_Data(
Name=row[1],
Year=row[2],
Other=list())
My_Dictionary[row[0]] = info
My_Dictionary[row[0]].Other.append(row[3])
CodePudding user response:
- Don't use nested classes unless you really need to and know how.
self.Name: str
is an annotation that does nothing; your constructor is not setting any of the fields, hence "no attribute". You would doself.Name: str = Name
to assign them, but...- ... it's easier to use a
dataclass
, that figures out the constructor for you. - Then,
Data
andinfo
are not the same. Your IDE should highlight one as unused, which should already be a clue that you're not doing something right.
All in all:
import dataclasses
@dataclasses.dataclass
class My_Data:
Name = str
Year = float
Other: list
class Page1(tk.Frame):
def __init__(self, master, other, **kw):
super().__init__(master, **kw)
self.configure(bg="white")
def function1(self):
My_Dictionary = {}
x = cursor.execute("sql")
for row in x.fetchall():
if row[0] not in My_Dictionary:
info = My_Data(
Name=row[1],
Year=row[2],
Other=list(),
)
My_Dictionary[row[0]] = info
My_Dictionary[row[0]].Other.append(row[3])
print(My_Dictionary)
CodePudding user response:
The specific problem you're asking about is caused by the fact that your MyData
class's __init__
method doesn't actually do anything.
class My_Data():
def __init__(self, Name, Year, Other):
self.Name: str
self.Year: float
self.Other: list[int]
These statements are type hints and do not actually assign any attributes to the instance of your class. You can keep them as type hints are useful, but they should be defined outside any method and without self
. And if you're using type hints, might as well put 'em on the arguments to __init__
too.
So you want something like this:
class My_Data():
Name: str
Year: int
Other: list[int]
def __init__(self, Name: str, Year: int, Other: list[int]):
self.Name = Name
self.Year = Year
self.Other = Other
(Note I changed Year
to an integer.)
CodePudding user response:
The error you're seeing is a AttributeError, which means that the object you're trying to access a property or method on doesn't have that attribute. In this case, the error message is saying that the My_Data object has no attribute Other.
The problem seems to be that you are trying to access; My_Dictionary[row[0]].Other.append(row[3]) but Other is not a proper of the My_Data class.
It seems that you have defined 'Other' attribute in the constructor of class 'My_Data' but in the function1, you are trying to access it as a property of the object instead of a attribute of the class.
class Page1(tk.Frame):
def __init__(self, master, other, **kw):
super().__init__(master, **kw)
self.configure(bg='white')
class My_Data():
def __init__(self, Name, Year):
self.Name: Name
self.Year: Year
self.Other = []
def function1(self):
My_Dictionary = {}
x = cursor.execute("sql")
for row in x.fetchall():
if row[0] not in My_Dictionary:
Data = My_Data(
Name=row[1],
Year=row[2])
My_Dictionary[row[0]] = Data
My_Dictionary[row[0]].Other.append(row[3])
print(My_Dictionary)