Skip to content

Instantly share code, notes, and snippets.

@majgis
Last active October 13, 2015 15:08
Show Gist options
  • Save majgis/4214307 to your computer and use it in GitHub Desktop.
Save majgis/4214307 to your computer and use it in GitHub Desktop.
Pass kwargs defined on class to class initialization
def DefaultKwargs(**init_kwargs):
"""Decorator factory for passing default kwargs to the decorated function.
Returns:
decorator function
"""
def decorator(func):
"""Recieves a function, then wraps it with wrapper_func
args:
func: callable function or method
returns:
func wrapped inside wrapper_func
"""
def wrapper_func(*args, **kwargs):
"""This is the outer wrapper of the function that was passed to decorator.
The args are passed untouched to the wrapped function.
The kwargs are used to update a copy of the initial kwargs that were
passed to the decorator.
"""
combo_kwargs = {}
combo_kwargs.update(init_kwargs)
combo_kwargs.update(kwargs)
func(*args, **combo_kwargs)
return wrapper_func
return decorator
class InitKwargsBase(type):
""" Metaclass to pass kwargs defined on a class to initialization.
The key word arguments(kwargs) are defined
on a child class using this format:
class Parent(InitKwargs):
class InitKwarg:
key_word1 = 'value'
key_word2 = 'value2'
Parent's __init__(**kwargs) function will receive:
combo_kwargs = {}
combo_kwargs.update(init_kwargs)
combo_kwargs.update(kwargs)
where init_kwargs = {'key_word1':'value', 'key_word2':'value2'}
A class factory(metaclass) wraps the init function and stores
the kwargs to pass at initialization time.
Altering InitKwargs on the class during runtime will have no effect.
The kwargs are stored in the closure of the init decorator,
when the class object is created.
The kwargs directly passed to __init__ override any defined on
the class.
"""
def __init__(cls, name, bases, dct):
super(InitKwargsBase, cls).__init__(name, bases, dct)
kwargs_cls = getattr(cls, 'InitKwargs', None)
if kwargs_cls:
kwargs = {}
for name in dir(kwargs_cls):
if not name.startswith('__'):
kwargs[name] = getattr(kwargs_cls, name)
init = cls.__init__
cls.__init__ = DefaultKwargs(**kwargs)(init)
class InitKwargs(object):
"""Class to pass kwargs defined on a class to initialization
See the metaclass, InitKwargsBase, for further details.
"""
__metaclass__ = InitKwargsBase
#test
if __name__ == '__main__':
class Parent(InitKwargs):
""""""
def __init__(self, **kwargs):
""""""
print kwargs
class Child(Parent):
""""""
class InitKwargs:
name = 'test'
x = Child()
#output: {'name': 'test'}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment