Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why __getitem__ cannot be classmethod?

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__ ?

like image 590
QwiglyDee Avatar asked Sep 16 '12 12:09

QwiglyDee


People also ask

What does __ Getitem __ do in Python?

__getitem__(x, i) . The method __getitem__(self, key) defines behavior for when an item is accessed, using the notation self[key] . This is also part of both the mutable and immutable container protocols. Unlike some other languages, Python basically lets you pass any object into the indexer.

What is @classmethod?

The @classmethod decorator is a built-in function decorator which is an expression that gets evaluated after your function is defined. The result of that evaluation shadows your function definition. A class method receives the class as the implicit first argument, just like an instance method receives the instance.

What is __ str __ in Python?

Python __str__()This method returns the string representation of the object. This method is called when print() or str() function is invoked on an object. This method must return the String object.

What is Staticmethod and Classmethod?

The static method does not take any specific parameter. Class method can access and modify the class state. Static Method cannot access or modify the class state. The class method takes the class as parameter to know about the state of that class.


1 Answers

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.

like image 155
lvc Avatar answered Sep 22 '22 10:09

lvc