为什么__getitem__不能成为classmethod?

qMa*_*Max 15 python class-method

假设以下课程:

class Class(object):
    @classmethod
    def getitem(*args):
        print 'getitem %s' % (args,)
    @classmethod
    def __getitem__(*args):
        print '__getitem__ %s' % (args,)
Run Code Online (Sandbox Code Playgroud)

getitem方法的行为符合预期:它Class作为第一个arg __getitem__接收,但type作为第一个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')
Run Code Online (Sandbox Code Playgroud)

背后有什么魔力__getitem__

lvc*_*lvc 21

在类上查找特殊方法,而不是在实例上查找 - 与首先在实例上查找的常规方法不同.请参阅Python数据模型文档中的特殊方法查找.

考虑Class作为一个例子type,这意味着当你这样做

Class.getitem(test)
Run Code Online (Sandbox Code Playgroud)

它首先看到你告诉它的确切内容:一个Class名为自己的属性的方法getitem.但是,当你使用

Class[test]
Run Code Online (Sandbox Code Playgroud)

它会跳过这个,然后直接进入type(成为类Class或其元类),然后调用type.__getitem__(Class, test).那么,究竟是怎么回事是不是__getitem__得到type的第一个参数(它仍然会得到Class,因为如果你不明确Class.__getitem__(test)),它的__getitem__了Python在这种情况下,寻找不存在.要使其存在,您需要定义自己的元类Class,将其定义为实例方法,而不是将其定义Class为类方法.


ber*_*eal 11

当您致电时x[test],口译员会检查type(x)__getitem__属性.如果是Class[test]它的Class元类,即type.如果您想拥有一个类__getitem__,请在新的元类中定义它.(不用说,这是一种魔术,就像你用元类做的那样)

class Meta(type):
    def __getitem__(self, arg):
        print "__getitem__:", arg


class X(object):
    __metaclass__ = Meta

X['hello'] # output: __getitem__ hello
Run Code Online (Sandbox Code Playgroud)