Dynamic Python Mixins
I was pretty surprised to find out how straightforward it is to create mixin factories and templates in Python. I had a bunch of classes with attributes that needed special getter and setter methods with JSON serialization logic inside of them.
class Model:
parameter = None
def get_parameter(self):
return json.loads(self.parameter)
def set_parameter(self, value)
return self.parameter = json.dumps(value)
With several such classes, each containing different amount of attributes that need JSON setters and getters I was aiming to keep it DRY with mixins, but since the number of attributes and their names differ between classes, I’d need a template mixin, a mixin factory that generates mixins dyanmically.
Here we go:
def JSONAttributes(attributes):
class JSONAttributeMixin:
pass
def create_setter(attribute):
def setter(self, value):
setattr(self, attribute, json.dumps(value))
return setter
def create_getter(attribute):
def getter(self):
return json.loads(getattr(self, attribute))
return getter
for attribute in attributes:
setattr(JSONAttributeMixin, 'set_' + attribute, create_setter(attribute))
setattr(JSONAttributeMixin, 'get_' + attribute, create_getter(attribute))
return JSONAttributeMixin
As you can see, the factory creates an inner class that will be used as a mixin, and for each attribute creates a getter and setter functions and tack them onto the mixin.
class ModelA(JSONAttributes(['permissions', 'rules'])):
pass
m = ModelA()
m.set_rules([{'name': 'general'}])
m.set_permissions([{'type': 'all'}])
m.get_rules()
# [{'name': 'general'}]
m.get_permissions()
# [{'type': 'all'}]
m.permissions
# '[{"type": "all"}]'
Easy ?