Reputation: 761
I'm in a slightly tricky situation with a list subclass.
The list class I'm using has overridden __iter__
and __getitem__
in order to return something slightly different from what's actually stored internally (this is because this requires processing time which was wanted to be only done when the item is first directly accessed)
My issue comes up in the following use case. Let's say, for the use of this example, that the overridden methods turn the internal values into strings.
>>> myList = MyList([1, 2, 3])
>>> standardList = list(["a", "b", "c"])
>>>
>>> for item in myList:
>>> print item
"1"
"2"
"3"
>>> newList = standardList + myList
>>> for item in newList:
>>> print item
"a"
"b"
"c"
1
2
3
So what I'm after here is how the values are pulled from myList
when standardList + myList
is run, so that I can ensure that newList
has had the relevant modifications made.
Incidentally, I'm well aware that I could get this working if I overrode MyList.__add__
and then did myList + standardList
, but this is in a module that is used elsewhere, and I'd rather ensure that it works the right way in both directions.
Thanks
Upvotes: 0
Views: 78
Reputation: 250951
To ensure if works in both directions you should define both override both __add__
and __radd__
in your MyList
class. Quoting from data model page(7th bullet point)*:
Exception to the previous item: if the left operand is an instance of a built-in type or a new-style class, and the right operand is an instance of a proper subclass of that type or class and overrides the base’s
__rop__()
method, the right operand’s__rop__()
method is tried before the left operand’s__op__()
method.
So, your code will look like:
class MyList(list):
def __radd__(self, other):
return MyList(list.__add__(other, self))
*Note that the proper subclass thing mentioned in Python 2 docs is actually a documentation bug and they fixed it in Python 3:
If the right operand’s type is a subclass of the left operand’s type and that subclass provides the reflected method for the operation, this method will be called before the left operand’s non-reflected method. This behavior allows subclasses to override their ancestors’ operations.
Upvotes: 2
Reputation: 462
You can simply pass the result of list addition as in the constructor of MyList, like:
newList = MyList(standardList + myList)
Upvotes: 0