I want to add static methods to a class thanks to a metaclass. Is this possible? Here is what I tried:
from django.conf import settings
import six
class Setting(object):
def __init__(self, name=None, default=None):
self.name = name
self.default = default
class Metaclass(type):
def __new__(mcs, cls, bases, dct):
new_attr = {}
for name, val in dct.items():
if isinstance(val, Setting):
# populate name
if val.name is None:
val.name = name.upper()
# add a static getter
new_attr['get_%s' % name] = staticmethod(lambda: getattr(
django_settings, val.name, val.default))
new_attr[name] = val
return super(Metaclass, mcs).__new__(mcs, cls, bases, new_attr)
class AppSettings(six.with_metaclass(Metaclass)):
pass
I also tried to defer the assignment of the static getter after the class is created, like:
new_class = super(Metaclass, mcs).__new__(mcs, cls, bases, {})
# loop on dct, memorize what methods to set
for name, method in deferred_methods.items():
setattr(new_class, name, method)
return new_class
It seems to be working, but when I run some tests with a subclass of AppSettings and some settings in it, then everything is mixed up. Behaviour changes everytime I re-run the tests. It this due to the use of lambdas?