Python decorating property setter with list
16,642
Solution 1
I define a method append() and a method extend() for the class object. It respectively appends to member myList and extends member myList.
global globalList
globalList = []
class MyList():
def __init__(self):
self._myList = [1, 2, 3]
@property
def myList(self):
return self._myList + globalList
@myList.setter
def myList(self, val):
self._myList = val
def append(self, val):
self.myList = self.myList + [val]
return self.myList
def extend(self, val):
return self.myList.extend(val)
mL1 = MyList()
print("myList: ", mL1.myList)
mL1.append(4)
print("after appending a 4, myList: ", mL1.myList)
mL1.myList.extend([5,6,"eight","IX"])
print("after extend, myList: ", mL1.myList)
result is
>>>
('myList: ', [1, 2, 3])
('after appending a 4, myList: ', [1, 2, 3, 4])
('after extend, myList: ', [1, 2, 3, 4, 5, 6, 'eight', 'IX'])
Solution 2
I would subclass list
and override a few methods:
import itertools
class ExtendedList(list):
def __init__(self, other=None):
self.other = other or []
def __len__(self):
return list.__len__(self) + len(self.other)
def __iter__(self):
return itertools.chain(list.__iter__(self), iter(self.other))
def __getitem__(self, index):
l = list.__len__(self)
if index > l:
return self.other[index - l]
else:
return list.__getitem__(self, index)
It should work with just about everything:
In [9]: x = ExtendedList([1, 2, 3])
In [10]: x
Out[10]: [1, 2, 3]
In [11]: x.append(9)
In [12]: x
Out[12]: [9, 1, 2, 3]
In [13]: x.extend([19, 20])
In [14]: x
Out[14]: [9, 19, 20, 1, 2, 3]
In [15]: sum(x)
Out[15]: 54
Author by
drerD
Updated on June 04, 2022Comments
-
drerD about 2 years
globalList = [] class MyList: def __init__(self): self._myList = [1, 2, 3] @property def myList(self): return self._myList + globalList @myList.setter def myList(self, val): self._myList = val mL1 = MyList() print("myList: ", mL1.myList) mL1.myList.append(4) print("after appending a 4, myList: ", mL1.myList) mL1.myList.extend([5,6,"eight","IX"]) print("after extend, myList: ", mL1.myList)
Result:
myList: [1, 2, 3] after appending a 4, myList: [1, 2, 3] after extend, myList: [1, 2, 3]
The problem I am facing is that mL1.myList.append(4) and mL1.myList.extend([5,6,"eight","IX"]) do not modify the _myList attribute in the mL1 object. How could I do to resolve the problem?
-
drerD about 11 yearsHi thanks for the answer, it's interesting to see how you implement it. Hope you don't mind me asking some simple question: self.other = other or [], is short-circuit evaluation used here? so if the other parameter is not provided, then it's going to be empty list?
-
Blender about 11 years@user14042: Yep, if
other
is truthy (notNone
or an empty list in this case), it'll be returned. If not, the other side will be. -
drerD about 11 yearsThnak you for the suggestion!
-
user1346466 over 8 yearsThe code is highly broken :) MyList does not derive from object, which breaks the setter property, so after assigning to myList it will be a plain list. Once this is fixed, append() will add globalList to _mylist for every call. The extend implementation is broken too, it should extend _myList, otherwise it would only extend the temporary list returned by the property. And last, the example is calling mL1.myList.extend instead of mL1.extend.