重载实例[key] += val

Overload instance[key] += val

我正在编写一个 Java 集合 class,旨在与 Jython 一起使用。我希望最终用户能够以这种方式操作集合:

myCollection = MyJavaCollection()
myCollection[0] += 10.;
a = myCollection[0]; //a = 10
myCollection[0] += 20.;
b = myCollection[0]; //b = 20

我在Python文档中找到的是以下方法:

我怎样才能混合使用两者来做我想做的事?

请注意 myCollection[0] += 10.; 实际上会被解释为:

myCollection.__setitem__(0,  myCollection.__getitem__(0).__iadd__(10.))

因此,要完成这项工作,您需要实施:

  • __getitem____setitem__MyJavaCollection 上;和
  • __iadd__(或 __add__,如果 __iadd__ 未实现,Python 将回退到 .__getitem__ ] 将 return,而不是 MyJavaCollection 本身 - 如果它将 return 已经实现加法的东西,比如你示例中的 floats,你很好。

快速演示:

>>> class Container(object):

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

    def __getitem__(self, key):
        print "Container.__getitem__"
        return self.contained

    def __setitem__(self, key, val):
        print "Container.__setitem__"
        self.contained = val


>>> class Contained(object):

    def __add__(self, other):
        print "Contained.__add__"
        return "foo"


>>> test = Container(Contained())
>>> test[0] += 1
Container.__getitem__
Contained.__add__
Container.__setitem__
>>> test.contained
'foo'

你原来的问题有一个列表作为索引传递,所以我写这篇文章是假设你想访问二维列表的第 (i, j) 个元素。你可以通过定义你的 class 来做到这一点:

class MyJavaCollection:
    def __init__(self, values):
        self.values = values

    def __getitem__(self, indices):
        """
        Returns the item at index (i, j) given an index list [i, j].
        """
        return self.values[indices[0]][indices[1]]

    def __setitem__(self, indices, value):
        """
        Sets the (i, j)th item to the input value given an input
        index list [i, j].
        """
        self.values[indices[0]][indices[1]] = value

在这里,当您传递索引列表时,您正在重载 __getitem____setitem__ 方法来检索或设置 values 列表中的第 (i, j) 个元素 [i, j]。如果您的值只是数字,那么语法 myCollection([1, 1]) += 10 会将 10 添加到 values[1][1].

如另一个答案所述,如果您不只是在对象中存储数字,那么您可能需要覆盖任何 class 数据的 __add____iadd__ 方法包括获得您想要的行为。

测试我的例子class:

>> my_list = [[1, 2, 3], [4, 5, 6]]
>> my_list[1][1]
   5
>> my_collect = MyJavaCollection(my_list)
>> my_collect[[1, 1]]
   5
>> my_collect[[1, 1]] += 5
>> my_collect[[1, 1]]
   10

documentation on special method names 为您提供了关于此类特殊方法的所有信息。如果您不确定您可能需要重载什么方法,它可能是一个搜索的好地方。