27

I have a class like this one:

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)

In my main code, I create a list of MyClass instances called myClassList. In a line I have to check if an item with a given id already exists. I do it in this way:

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

The second line in that code gives this error:

'MyClass' object has no attribute '__getitem__'

How can I fix?

captainblack
  • 4,107
  • 5
  • 50
  • 60
floatingpurr
  • 7,749
  • 9
  • 46
  • 106
  • 1
    You need to add a `__getitem__` – Padraic Cunningham Aug 04 '15 at 10:45
  • 2
    ...you could implement `__getitem__`! Alternatively, use `item.id` instead of `item['id']`. Note also that you're assigning `self.id = a`, which is likely not what you intended, and aren't compliant with [the style guide](http://www.python.org/dev/peps/pep-0008/). – jonrsharpe Aug 04 '15 at 10:45

5 Answers5

32

item is not a dictionary but a class so it has different syntax for accessing members. Access id this way instead:

item.id
SuperBiasedMan
  • 9,814
  • 10
  • 45
  • 73
hiro protagonist
  • 44,693
  • 14
  • 86
  • 111
20

If you actually wanted to be able to access your attributes using inst["attr"] and to explain your error, you would need to add a __getitem__ to you class:

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)
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
4

As others have noted, you can simply use

item.id

However, sometimes you do need to use this syntax if you are accessing a field dynamically:

item[dynamicField]

In that case, you can use the __getitem__() syntax as Anand suggested, however it is safer to use python's wrapper for __getitem__:

getattr(item, dynamicField)
Aidan Hoolachan
  • 2,285
  • 1
  • 11
  • 14
1

Like the error suggests, you can only use subscript on class instances, if the class defines a __getitem__() instance method.

As id is an attribute of the instance, you should use - item.id instead of item['id'] .

Example -

recent_item = next( (item for item in myClassList if item.id == id), None )
Anand S Kumar
  • 88,551
  • 18
  • 188
  • 176
1

id is an attribute of MyClass instance, you have to access it as item.id

recent_item = next( (item for item in myClassList if item.id == id), None )
Anbarasan
  • 1,197
  • 13
  • 18