from the Python documentation, I see that you can set methods for handling properties transparently:
class C(object):
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")
Now assume that C._x
is a list. In init it is simply set to []
. So if I do the following:
c = C()
c.x = [1,2,3]
c.x
will be set to [1,2,3]
. What I want to be able to do now is
#...
c.x += 4
So that c.x
is now [1,2,3,4]
. The example is trivial, but obviously, I'd want the setx
and getx
methods to include some sort of processing and checks. Otherwise, using this approach would be silly.
Edit: It might be good enough to just use the __add__
method on C
to enforce the behaviour, but I wondered if it was possibly to put the behaviour on the property instead of the whole class
You can't overload operator for a specific attribute, because :
c.x += 4
# is equivalent to
c.x.__iadd__(4)
So in fact you are calling the __iadd__
operator of list. If you want to be able to do that, you have to create a new class, extending list, and overload operator __iadd__
or __add__
.
class SuperList(list):
def __iadd__(self, other):
if type(other) == list or type(other) == SuperList:
return super(SuperList, self).__iadd__(other)
return super(SuperList, self).__iadd__([other])
No, that won't work.
Basically, here's what happens:
c.x += 4
This code is equivalent to this:
var temp = c.x
temp += 4
c.x = temp
However, temp
here will be the list of 3 values, and this code doesn't work:
temp = [1, 2, 3]
temp += 4
You get:
TypeError: 'int' object is not iterable
So this has nothing to do with the property, and everything to do with the fact that the code needs to look like this:
temp += [4]
So this works:
c.x += [4]
This cannot:
c.x += 4
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With