[BangPypers] Adding mixing at run-time

Deepu Thomas Philip deepu.dtp at gmail.com
Thu Oct 9 12:56:25 CEST 2014


On Wed, Oct 8, 2014 at 4:19 PM, Anand Chitipothu <anandology at gmail.com>
wrote:

> 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.
>
>
While trying to remove logic that does not belong in the place module,
you introduced *place* into two other modules where it does not belong.

I did not understand the approach completely.
>From a config file how does one achieve plugin like architecture?

What do you guys think of this approach?
> Is this a good practice?
> Are there any know flaws in this approach?
>

Not sure if this is a flaw or expected behaviour

I could not get a Place + UserMixin instance and a Place + LinksMixin
instance to coexist
in the same scope at the same time.
Importing any of the mixins led to pollution of existing Place instances.

from place import Place
p = Place("bangalore")
from user import UserMixin
print p.get_links()                   # outputs 'links-of-bangalore'




> How did you solve that issue when you faced similar situation?


Any reason to not use a builder pattern or a factory method pattern?



>
>
Anand
> _______________________________________________
> BangPypers mailing list
> BangPypers at python.org
> https://mail.python.org/mailman/listinfo/bangpypers
>


More information about the BangPypers mailing list