为什么?getitem?不能是classmethod?

2024-04-24 23:22:17 发布

您现在位置:Python中文网/ 问答频道 /正文

假设以下类别:

class Class(object):
    @classmethod
    def getitem(*args):
        print 'getitem %s' % (args,)
    @classmethod
    def __getitem__(*args):
        print '__getitem__ %s' % (args,)

getitem方法的行为与预期一样:它接收Class作为第一个参数,但是__getitem__接收{}作为第一个参数:

^{pr2}$

__getitem__背后有什么魔力?在


Tags: 方法参数objectdefargs类别classprint
2条回答

当您调用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

特殊方法是在类上查找的,而不是在实例上查找的-不像常规方法那样首先在实例上查找。请参见Python数据模型文档中的Special method lookup。在

Class看作type的实例,这意味着

Class.getitem(test)

它首先查找您告诉它的内容:Class自身属性中名为getitem的方法。但是,当你使用

^{pr2}$

它跳过这个,直接转到type(是Class的类,或者它的元类),因此调用type.__getitem__(Class, test)。所以,__getitem__得到了type作为它的第一个参数(它仍然会得到Class,如果你显式地Class.__getitem__(test),它仍然会得到{}),而是Python在本例中寻找的__getitem__并不存在。要使其存在,您需要为将其定义为实例方法的Class定义自己的元类,而不是在Class上将其定义为类方法。在

相关问题 更多 >