Skip to content

Instantly share code, notes, and snippets.

@Podshot
Last active February 26, 2016 16:07
Show Gist options
  • Save Podshot/575e92b818d7413de01c to your computer and use it in GitHub Desktop.
Save Podshot/575e92b818d7413de01c to your computer and use it in GitHub Desktop.
Crazy idea to have a list run callback functions when the data is manipulated. Performance is probably bad, and the implementation probably could be better, but it gets the job done. The name could also be a little more creative
class EventedList(list):
def __init__(self, data):
super(EventedList, self).__init__(data)
self._events = {}
# --- Event Functions ---
def register(self, function, target):
func = self._getEventName(target)
if func not in self._events:
self._events[func] = []
self._events[func].append(function)
def unregister(self, function):
for event in self._events.keys():
if function in self._events[event]:
self._events[event].remove(function)
def _getEventName(self, event):
return str(event).split()[2]
# --- Reimplemented Functions ---
def append(self, object):
old = self[:]
super(EventedList, self).append(object)
for func in self._events[self._getEventName(self.append)]:
func(old, self, object)
def insert(self, index, object):
old = self[:]
super(EventedList, self).insert(index, object)
for func in self._events[self._getEventName(self.insert)]:
func(old, self, index, object)
def remove(self, value):
old = self[:]
super(EventedList, self).remove(value)
for func in self._events[self._getEventName(self.remove)]:
func(old, self, value)
def pop(self, index=-1):
old = self[:]
value = super(EventedList, self).pop(index)
for func in self._events[self._getEventName(self.pop)]:
func(old, self, index, value)
def reverse(self):
old = self[:]
super(EventedList, self).reverse()
for func in self._events[self._getEventName(self.reverse)]:
func(old, self)
def sort(self, cmp=None, key=None, reverse=False):
old = self[:]
super(EventedList, self).sort(cmp, key, reverse)
for func in self._events[self._getEventName(self.sort)]:
func(old, self, cmp, key, reverse)
def __setitem__(self, index, value):
old = self[:]
super(EventedList, self).__setitem__(index, value)
for func in self._events[self._getEventName(self.__setitem__)]:
func(old, self, index, value)
def __delitem__(self, index):
old = self[:]
deleted_value = self[index]
super(EventedList, self).__delitem__(index)
for func in self._events[self._getEventName(self.__delitem__)]:
func(old, self, index, deleted_value)
from EventedList import EventedList
class Test:
def __init__(self):
self.old = [0,1,2,3,4,5,6,7,8,9,10]
self.list = EventedList(self.old)
self.list.register(self.testAppend, self.list.append)
self.list.register(self.testInsert, self.list.insert)
self.list.register(self.testRemove, self.list.remove)
self.list.register(self.testPop, self.list.pop)
self.list.register(self.testReverse, self.list.reverse)
self.list.register(self.testSort, self.list.sort)
self.list.register(self.testSetItem, self.list.__setitem__)
self.list.register(self.testDelItem, self.list.__delitem__)
self.list.append(11)
self.list.append(12)
self.list.insert(1, 100)
self.list.remove(9)
self.list.unregister(self.testRemove)
self.list.remove(7)
self.list.pop(3)
self.list.pop()
self.list.reverse()
self.list.reverse()
self.list.sort()
self.list[1] = 2000
del self.list[2]
def testAppend(self, old, new, value):
print "Changed {} to {} by appending {}".format(old, new, value)
def testInsert(self, old, new, index, value):
print "Changed {} to {} by inserting {} at {}".format(old, new, value, index)
def testRemove(self, old, new, value):
print 'Changed {} to {} by removing {}'.format(old, new, value)
def testPop(self, old, new, index, value):
print "Changed {} to {} by popping {} from index {}".format(old, new, value, index)
def testReverse(self, old, new):
print "Reversed {} to {}".format(old, new)
def testSort(self, old, new, cmp, key, reverse):
print "Sorted {} to {} with arguments (cmp={}, key={}, reverse={})".format(old, new, cmp, key, reverse)
def testSetItem(self, old, new, index, value):
print "Changed {} to {} by 'self.list[{}] = {}".format(old, new, index, value)
def testDelItem(self, old, new, index, deleted_value):
print "Change {} to {} by 'del self.list[{}]' and deleted value '{}'".format(old, new, index, deleted_value)
Test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment