Divergent classes in Python
During the development of a web crawler, I was trying to generalize the process as much as possible so to handle multiple types of data extraction from websites.
I realized that there were a lot of classes that had a property in which was stored either a single instance or a list of of instances of the same class as children.
Something like this:
class A:
def __init__(self, a, b, children):
self.a = a
self.b = b
self.children = children # either an instance of A, or a list of elements of type A
@property
def children(self):
return self._children
@children.setter
def children(self, xch):
self._children = xch
Something quite a like a tree, and I realized that I had to use something like mappers on such classes.
From such needs arised the term divergent classes
When you would need to apply some procedure of logic on an element of type A and all of its children and children's children... you'd use this a decorator like this:
@divergent("children")
class A:
def __init__(self, a, b, children):
self.a = a
self.b = b
self.children = children # either an instance of A, or a list of elements of type A
Specifying that the class is divergent and giving it as a parameter the name of the divergent property, or as I like to call it, the divergence point.
The usage will be as follows:
# Let's suppose that this object has two children, and each of them has one child.
root = A("root's a attribute", "root's b attribute") # I would not explicitly pass in the children for the sake of simplicity.
def _print_a(AInstance):
print("%s" % AInstance.a)
root.diverge(_print_a);
# output
# root's a attribute
# child 1's a attribute
# child 1's child a attribute
# child 2's a attribute
# child 2's child a attribute
The decorator is available in this gist
You might have though of using inheritence, so did I, but some designs do not allow such thing, and this decorator allows the flexibilty of supporting multiple classes with different naming to their 'divergence points' attribute, that is the attribute that hosts the children.
Thanks for reading, please leave your opinion in the comments section below, I'd love to know how useful was this. And if you like it more, start the gist.