Skip to content

Instantly share code, notes, and snippets.

@Faheetah
Last active November 30, 2018 21:15
Show Gist options
  • Select an option

  • Save Faheetah/064ae3b5d22ecfeeb40257b3ba66fdf3 to your computer and use it in GitHub Desktop.

Select an option

Save Faheetah/064ae3b5d22ecfeeb40257b3ba66fdf3 to your computer and use it in GitHub Desktop.
Python Decorator Foo
# 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