我正在编写一个Java集合类,用于Jython。我希望最终用户能够以这样的方式操作集合:
myCollection = MyJavaCollection()
myCollection[0] += 10.;
a = myCollection[0]; //a = 10
myCollection[0] += 20.;
b = myCollection[0]; //b = 20我在Python文档中发现的是以下方法:
__getitem__和__setitem__方法应该完成括号操作符重载的工作。__iadd__方法是+=的良好候选方法。我怎么才能把两者混在一起做我想要的呢?
发布于 2015-07-23 15:38:40
请注意,myCollection[0] += 10.;实际上将被解释为:
myCollection.__setitem__(0, myCollection.__getitem__(0).__iadd__(10.))因此,要完成这项工作,您需要实现:
__getitem__和__setitem__ on MyJavaCollection;以及__iadd__ (或者__add__,如果__iadd__没有实现的话)将返回任何.__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'发布于 2015-07-23 16:03:08
您最初的问题中有一个列表作为索引传递,所以我编写了这个假设您想要访问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__方法,以检索或设置values列表中的(i, j)th元素。如果您的值只是数字,那么语法myCollection([1, 1]) += 10将向values[1][1]添加10。
正如另一个答案所述,如果您不是简单地将数字存储在对象中,那么您可能需要在您的数据包含的任何类上覆盖__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关于特殊方法名称的文档为您提供了您想要了解的关于这种特殊方法的一切信息。如果您不确定需要哪种方法来重载,这可能是一个搜索的好地方。
https://stackoverflow.com/questions/31591873
复制相似问题