3

This is a question I am asking only out of curiosity.

I answered this question about generators, and the exception that got raised surprised me. I would expect both of these to give the same exception:

# Create a lame generator
a = (x for x in range(5))

# This raises a TypeError with the message "'generator' object is not subscriptable"
# I completely expected this.
a[0]

# Why doesn't this give the same message?
# This raises a TypeError with the message "'generator' object does not support item assignment"
# which is (I think) the exception raised when trying to assign to an immutable object.
a[0] = 2

I would expect both of them to raise a TypeError with the message "'generator' object is not subscriptable", because it seems to be more important. Why give the message that you can't assign, whenever trying to access an element would already raise an exception?

Not sure if this is relevant, but I'm using Python 3.3.

Community
  • 1
  • 1
Cody Piersall
  • 8,312
  • 2
  • 43
  • 57

1 Answers1

4

Those two operations invoke different methods; accessing a subscript invokes __getitem__(), whereas setting a subscript invokes __setitem__(). Each raises a different exception because each is a different operation conceptually.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • Thanks for the quick response! Is the `__setitem__` called before `__getitem__`? Could I rewrite `a[0]` as a.__getitem__(), and `a[0] = 'puppy'` as `a.__getitem__().__setitem__('puppy')`? Or am I just thinking about this wrong? – Cody Piersall Nov 22 '13 at 02:14
  • 2
    @CodyPiersall: `a[0] = 'puppy'` is `a.__setitem__(0, 'puppy')`. There is no get operation when assigning. – Ignacio Vazquez-Abrams Nov 22 '13 at 02:16
  • Thanks! Exactly the answer I was looking for. Give me 2 minutes and I'll accept it. Bonus points for the links to the docs. – Cody Piersall Nov 22 '13 at 02:16