Last active
November 30, 2018 21:15
-
-
Save Faheetah/064ae3b5d22ecfeeb40257b3ba66fdf3 to your computer and use it in GitHub Desktop.
Python Decorator Foo
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
| # I always get confused with decorators because of all the nesting and where all of the arguments go | |
| # Reference of using decoratores with arguments and with classes | |
| ## Very Simple Decorator | |
| def foo(f): | |
| # Inner function that must be returned | |
| def decorator(): | |
| print('decorator') | |
| # Will be bar() from the below wrapped call | |
| f() | |
| return decorator | |
| @foo | |
| def bar(): | |
| print('bar') | |
| bar() | |
| ## Decorator with args and kwargs | |
| # Needs an extra layer of functions to capture the args from the decorator | |
| def foo_args(*args, **kwargs): | |
| def foo(f): | |
| # The decorator() layer captures any arguments from the direct function | |
| def decorator(*bar_args, **bar_kwargs): | |
| # We can do something with them | |
| print('decorator', args, kwargs) | |
| # And then pass them through as is to the function | |
| f(*bar_args, **bar_kwargs) | |
| # Must return both functions | |
| return decorator | |
| return foo | |
| @foo_args('fooargs', fookwarg='fookwarg') | |
| def bar_args(*args, **kwargs): | |
| print('bar_args', args, kwargs) | |
| bar_args('bararg', barkwarg='barkwarg') | |
| ## Decorator in a class | |
| class FooClass(): | |
| # Pretty much the same as regular decorators | |
| def foo(func): | |
| # Only exception is that the decorator() layer must also include self | |
| def decorator(self): | |
| print('class decorator') | |
| # And pass it through to self | |
| return func(self) | |
| return decorator | |
| @foo | |
| def method(self): | |
| print('method') | |
| fooclass = FooClass() | |
| fooclass.method() | |
| ## A pretty crazy example when you need to be a horrible person and use registry pattern within a class via decorators | |
| class FooClassArgs(): | |
| # Wrapper equivalent to foo_args as before, we take a single argument as the registry key | |
| def foo_args(key): | |
| def foo(func): | |
| # Follows the same general structure as using a decorator with args, plus using a decorator in a class | |
| # This function is called when create_bar is called, self is not in the scope of the decorator | |
| def decorator(self, *args, **kwargs): | |
| # Still call the func as usual, nothing magic here we have self and our args, we just directly call func | |
| return func(self, *args, **kwargs) | |
| return decorator | |
| return foo | |
| # This will run through the decorator with 'createBar' as key | |
| @foo_args('createBar') | |
| def create_bar(self, *args, **kwargs): | |
| print('bar', args, kwargs) | |
| fooclassargs = FooClassArgs() | |
| fooclassargs.create_bar('foo', bar='baz') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment