Last Updated: September 30, 2021
·
342
· hamzaouaghad

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.