Last active
October 13, 2015 15:08
-
-
Save majgis/4214307 to your computer and use it in GitHub Desktop.
Pass kwargs defined on class to class initialization
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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