使用' self'方括号

时间:2014-11-14 17:18:40

标签: python

我想知道我是否可以使用像self[avariable]这样的方括号,所以我已经实现了__getitem__。我试过的代码:

class myclass:
    def __getitem__(self,index):
        return self[index]

babe = myclass()
print babe[4]

当我运行它时显示:

File "C:/Python27/df", line 3, in __getitem__
    return self[index]

递归。

如何在Python中使用self[name]__getitem__之类的变量?

3 个答案:

答案 0 :(得分:4)

您的课程需要索引,而不是self。例如,在此类foo中,它有一个成员变量data,它是一个列表。因此,例如,索引操作可以从列表data中索引。

class foo():
    def __init__(self, l):
        self.data = l

    def __getitem__(self, index):
        return self.data[index]

>>> a = foo([1,2,3])
>>> a[1]
2

答案 1 :(得分:1)

这是一个非常简单的类来演示理论:

class Indexable(object):

    def __getitem__(self, index):
        print("You indexed me with {}.".format(index))

在使用中,然后:

>>> i = Indexable()
>>> i[12]
You indexed me with 12.

我们可以清楚地看到i[12]已解析为Indexable.__getitem__(i, 12)

这种情况随处可见 - 即使您在实例方法(包括self[avariable] )中调用__getitem__,您最终也会调用Indexable.__getitem__(self, avariable)。如果您在self[avariable]中加入Indexable.__getitem__,这就解释了无限循环。

在Python中总会如此,如果不自行重写,则无法重新定义此语法。这是一种"魔术方法",就像str(instance)调用Class.__str__(instance)一样。


在实践中,您通常希望为索引定义一些有用的行为,也许您想伪造numpy - 样式逗号分隔的索引:

class NotArray(object):

    def __init__(self, data):
        self.data = data

    def __getitem__(self, index):
        data = self.data
        for ind in index:
            data = data[ind]
        return data

这可以像:

一样使用
>>> arr = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
>>> arr[1, 1, 1]
Traceback (most recent call last):
  File "<pyshell#51>", line 1, in <module>
    arr[1, 1, 1]
TypeError: list indices must be integers, not tuple
>>> arr = NotArray([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
>>> arr[1, 1, 1]
8

请注意,我们现在已经为给定索引定义了要返回的数据的源。


您也可以使用它来实现非标准语法,就像我在回答这个问题时所做的那样:is it possible to add some new syntax in javascript?但是这通常是不鼓励的,因为这会让读者感到困惑。

答案 2 :(得分:0)

class myclass(list):
    def __getitem__(self, key):
        return super(myclass, self).__getitem__(key-1)

babe = myclass()
babe.append(1)
babe.append(2)
babe.append(3)
babe.append(4)
print babe[4]