Как создать список объектов, чтобы атрибуты и методы объекта подсказывались в IDE
Возникла потребность создать список классов на Python. класс используется для хранения данных и должен обладать своими методами, которые будут манипулировать с полями класса.
class B:
def __init__(self, a:str, b:str):
self.a = a
self.b = b
def foo(self):
pass
class A:
def __init__(self):
self.data_1: str
self.data_2: str
self.listB: list[B]
def foo(self):
pass
a = A()
b = B("ddd", "rrr")
a.listB.append(b)
при вызове append возникает ошибка: AttributeError: 'A' object has no attribute 'listB'
Не могу понять, что не так. Видимо я слишком засел на C++ и такие действия там проходят на ура. Я что-то делаю не так, но не могу понять, что именно.
Правлено:
После исправлений:
class B:
def __init__(self, a:str, b:str):
self.a = a
self.b = b
def foo(self):
pass
class A:
def __init__(self):
self.data_1: str
self.data_2: str
self.listB = []
def foo(self):
pass
a = A()
b = B("ddd", "rrr")
a.listB.append(b)
vala = a.listB[0].a
В строке vala = a.listB[0].a
не выпадает а после точки, как-будто нет поля класса B. Хотя все отрабатывает
Ответы (1 шт):
Поля с аннотациями должны быть описаны на уровне класса, а не в методе __init__
, тогда IDE будет их видеть. В __init__
нужно делать инициализацию, например присваивание начального значения полю listB
.
Пример кода:
class B:
a: str
b: str
def __init__(self, a: str, b: str):
self.a = a
self.b = b
def foo(self):
pass
class A:
data_1: str
data_2: str
listB: list[B]
def __init__(self):
self.listB = []
def foo(self):
pass
a = A()
b = B("ddd", "rrr")
a.listB.append(b)
Можно переписать через датаклассы, тогда не нужно будет вручную описывать __init__
, в том числе не перекладывать вручную параметры __init__
в одноименные атрибуты, и можно будет прямо при объявлении описать дефолтные значения:
from dataclasses import dataclass, field
@dataclass
class B:
a: str
b: str
def foo(self):
pass
@dataclass
class A:
data_1: str | None = None # Неизменяемые дефолтные значения можно прописать напрямую
data_2: str | None = None
listB: list[B] = field(default_factory=list) # Изменяемые нужно описывать через default_factory, иначе список будет общим для всех экземпляров класса
def foo(self):
pass
a = A()
b = B("ddd", "rrr")
a.listB.append(b)