I have an existing list instance, which in live code has references throughout. When a list reference is passed into a certain function, I need to ensure that all items in that list are valid from that point onwards (validate all list items then attach validation for future changes).
Creating a new class that overrides __setitem__ and friends whilst deriving from list provides the validation required (PropertyList shown below). The trouble is other parts of the code are pointing to the old list reference, and as this is part of a library where I cannot really ask developers to account for this (it breaks backwards compatibility and would chew up code in such a way as to be unnoticeable at first).
Is there anyway I can change the class of a list item “live” so that all references to the list will now call the modified __setitem__, etc methods?
class PropertyList(list):
def __init__(self, validator, *args, **kwargs):
self.__validator = validator
super(PropertyList, self).__init__(*args, **kwargs)
def __setitem__(self, key, value):
value = self.__validator(value)
super(PropertyList, self).__setitem__(key, value)
def append(self, value):
value = self.__validator(value)
super(PropertyList, self).append(value)
def extend(self, other):
other = map(self.__validator, other)
super(PropertyList, self).extend(other)
def insert(self, index, value):
value = self.__validator(value)
super(PropertyList, self).insert(index, value)
No, there is not. Even if you could replace
__class__attribute, you shouldn’t attempt to do that, it’s confusing and likely to break in subtle ways. If you need to create a validating list, you need to create a new object and use that instead of the old one.