why __getitem__ cannot be classmethod?

class-method, python

Solution

Special methods are looked up on the class, and not on the instance - unlike regular methods that are looked up on the instance first. See Special method lookup in the Python data model docs.

Thinking about `Class` as an instance of `type`, this means when you do

Class.getitem(test)

It looks first for exactly what you tell it: a method in `Class`'s own attributes called `getitem`. But, when you use

Class[test]

it skips this, and goes straight to `type` (being the class of `Class`, or its metaclass), and so calls `type.__getitem__(Class, test)`. So, what's happening isn't that `__getitem__` gets `type` as its first argument (it would still get `Class`, as it does if you explicitly `Class.__getitem__(test)`), its that the `__getitem__` that Python looks for in this case doesn't exist. To make it exist, you need to define your own metaclass for `Class` that defines it as an instance method, rather than defining it on `Class` as a classmethod.

Problem

Suppose following class: ``` class Class(object): @classmethod def getitem(*args): print 'getitem %s' % (args,) @classmethod def __getitem__(*args): print '__getitem__ %s' % (args,) ``` The getitem method behaves as expected: it receives `Class` as first arg, but `__getitem__` receives `type` as first arg: ``` calling Class.getitem(test) getitem (<class '__main__.Class'>, 'test') calling obj.getitem(test) getitem (<class '__main__.Class'>, 'test') calling Class[test] 'type' object has no attribute '__getitem__' calling obj[test] __getitem__ (<class '__main__.Class'>, 'test') ``` What is the magic there behind `__getitem__` ?

Original source