Объект MyClass не имеет атрибута '__getitem__'

У меня есть такой класс:

class MyClass(object):
    def __init__(self, id, a, b, c):
        self.myList     = []
        self.id         = id
        self.a          = a
        self.b          = b
        self.c          = c

    def addData(self, data):
        self.myList.append(data)

В моем основном коде я создаю список экземпляров MyClass, который называется myClassList. В строке я должен проверить, существует ли элемент с данным id. Я делаю это так:

id = 'foo' # in real code is set dynamically 
recent_item = next( (item for item in myClassList if item['id'] == id), None )

Вторая строка в этом коде дает эту ошибку:

Объект MyClass не имеет атрибута '__getitem__'

Как я могу исправить?

Ответ 1

item не словарь, а класс, поэтому он имеет различный синтаксис для доступа к членам. Доступ id таким образом:

item.id

Ответ 2

Если вы действительно хотели иметь доступ к вашим атрибутам с помощью inst["attr"] и объяснить вашу ошибку, вам нужно добавить __getitem__ к вашему классу:

class MyClass(object):
    def __init__(self, id, a, b, c):
        self.myList     = []
        self.id         = id
        self.a          = a
        self.b          = b
        self.c          = c

    def addData(self, data):
        self.myList.append(data)

    def __getitem__(self, item):
        return getattr(self, item)

Ответ 3

id является атрибутом экземпляра MyClass, вам нужно получить к нему доступ как item.id

recent_item = next( (item for item in myClassList if item.id == id), None )

Ответ 4

Как и в случае ошибки, вы можете использовать только индекс в экземплярах класса, если класс определяет метод экземпляра __getitem__().

Поскольку id является атрибутом экземпляра, вы должны использовать - item.id вместо item['id'].

Пример -

recent_item = next( (item for item in myClassList if item.id == id), None )

Ответ 5

Как уже отмечали другие, вы можете просто использовать

item.id

Однако иногда вам нужно использовать этот синтаксис, если вы обращаетесь к полю динамически:

item[dynamicField]

В этом случае вы можете использовать синтаксис __getitem __(), как предлагал Ананд, однако безопаснее использовать оболочку python для __getitem__:

getattr(item, dynamicField)