Created
April 4, 2012 17:03
-
-
Save bmc/2303869 to your computer and use it in GitHub Desktop.
Yet another way to do mixins in Python
This file contains hidden or 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
| import inspect | |
| def mixin(cls, *funcs): | |
| """ | |
| Mix the specified class into the current class. If function names (as | |
| strings) are passed, then only those functions are mixed in. | |
| mixin() MUST be called within a class definition. | |
| Example: | |
| class Mixin1(object): | |
| def foo(self): | |
| pass | |
| def bar(self): | |
| pass | |
| def baz(self) | |
| pass | |
| class X(object): | |
| mixin(Mixin1) # gets all the methods | |
| class Y(object): | |
| mixin(Mixin1, 'foo') # only gets foo | |
| class Z(object): | |
| mixin(Mixin1, 'foo', 'baz') # gets foo and baz, but not bar | |
| Adapted from: | |
| http://code.activestate.com/recipes/498124-real-mixins/ | |
| """ | |
| locals = inspect.stack()[1][0].f_locals | |
| if "__module__" not in locals: | |
| raise TypeError("mixin() must be invoked within a class definition") | |
| # Copy the class's dict. | |
| dict = cls.__dict__.copy() | |
| # The true ugliness. | |
| slots = dict.pop("__slots__", []) | |
| if slots and "__slots__" not in locals: | |
| locals["__slots__"] = ["__dict__"] | |
| else: | |
| locals["__slots__"] = [] | |
| names = set(funcs) if len(funcs) > 0 else set() | |
| new_dict = {} | |
| for name in dict: | |
| if not name.startswith("__"): | |
| if len(names) == 0 or name in names: | |
| locals["__slots__"].append(name) | |
| new_dict[name] = dict[name] | |
| # Mix the namespaces together. | |
| locals.update(new_dict) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment