[BangPypers] Adding mixing at run-time

Anand Chitipothu anandology at gmail.com
Wed Oct 8 12:49:06 CEST 2014


Hi,

I'm working on a slightly large application and I'm trying to model it as a
some kind of plugin architecture so that it modular and I can enable or
take out features without lot of code changes.

One of the issues I faced was that the wanted to add some methods to a
class only when a feature/plugin is enabled.

Here is a simplified version of what I have:

class Place(Mixable):
    def __init__(self, name):
        self.name = name

    def get_users(self):
        return "users-of-{}".format(self.name)

    def get_links(self):
        return "links-of-{}".format(self.name)

There are couple of issues with this.

1. The logic for computing users or links doesn't really belong to this
file. I wanted to that in a separate module for modularity.

2. The Place class will become too large to manage over time.

So, I came up with the following approach to address these issues.

# place.py

class Mixable(object):
    """Magic class to allow adding mixins to the class at run-time.
    """
    @classmethod
    def mixin(cls, mixin):
        """Decorator to add a mixin to the class runtime.
        """
        cls.__bases__ = cls.__bases__ + (mixin,)

class Place(Mixable):
    def __init__(self, name):
        self.name = name

# users.py
@Place.mixin
class UsersMixin(object):
    def get_users(self):
        return "users-of-{}".format(self.name)

# links.py
@Place.mixin
class LinksMixin(object):
    def get_links(self):
        return "links-of-{}".format(self.name)

p = Place('bangalore')
print(p.get_users())
print(p.get_links())

With this I was able to split the class into 3 files and now I have
flexibility of deciding which features enable from a config file.

What do you guys think of this approach?
Is this a good practice?
Are there any know flaws in this approach?
How did you solve that issue when you faced similar situation?

Anand


More information about the BangPypers mailing list