Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
533 views
in Technique[技术] by (71.8m points)

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...