重载实例[键]+=

2024-10-02 10:34:48 发布

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

我正在编写一个Java集合类,它将与Jython一起使用。我希望最终用户能够这样操作集合:

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

我在Python文档中发现了以下方法:

  • __getitem____setitem__方法应该完成括号运算符重载的工作。

  • __iadd__方法是+=的最佳候选方法。

我怎样才能把两者混合起来做我想要的呢?你知道吗


Tags: 方法文档运算符jythonjava括号getitemsetitem
2条回答

您最初的问题有一个作为索引传递的列表,因此我编写本文时假设您希望访问2D列表的第(i, j)元素。您可以通过以下方式定义类:

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__方法,以便在传递索引列表[i, j]时检索或设置(i, j)列表中的第(i, j)个元素。如果值只是数字,那么语法myCollection([1, 1]) += 1010添加到values[1][1]。你知道吗

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

测试示例类:

>> 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提供了您想知道的关于这种特殊方法的所有信息。如果您不确定需要重载什么方法,那么它可能是一个搜索的好地方。你知道吗

请注意myCollection[0] += 10.;的解释如下:

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

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

  • __getitem____setitem__MyJavaCollection上;和
  • __iadd__(或者__add__,如果__iadd__没有实现的话,Python会退回到这个位置)在上,不管.__getitem__返回的是什么,而不是MyJavaCollection本身-如果它返回的是已经实现了加法的东西,比如你的例子中的float,你就没事了。你知道吗

快速演示:

>>> 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'

相关问题 更多 >

    热门问题