Skip to content

Instantly share code, notes, and snippets.

@JimDennis
Created July 20, 2019 22:10
Show Gist options
  • Save JimDennis/08e1c32aa6b095b8456526128ab36279 to your computer and use it in GitHub Desktop.
Save JimDennis/08e1c32aa6b095b8456526128ab36279 to your computer and use it in GitHub Desktop.
Example of a naïve decorator function
def prefixer(fn, prefix):
'''Return a wrapper which prefix first (string) argument with prefix'''
def wrapper(output, *args, **kwargs):
output = '%s%s' % (prefix, output)
return fn(output, *args, **kwargs)
return wrapper
## Example of a decorator WITHOUT using the @wrapper syntactic sugar
## (to save ref to print if we want to use it later: old_print = print)
print = prefixer(print, 'Prefixed: ')
## Now the previous (builtin) print function is "wrapped" with our prefixer
## Tests:
print('foo')
## >>> Prefixed: foo
print('foo', 'bar', file=sys.stderr)
## >>> Prefixed: foobar ... but going to stderr
## Notice that the variable argument handling and the keyword argument (**kwargs) handling
## ... of the original function have been preserved. However the side-effect is that the
## first argument will to the wrapped function will be converted to a string and modified
## *before* it's passed into the original function.
## It's "naïve" because we didn't preserve certain metadata about the function:
print.__name__
## >>> wrapped
oprint.__name__
## >>> print
## functools.wraps is a decorator which will handle these details
## to use it in the example above we'd insert:
## @functools.wraps
## ... on a line just before def wrapper(....) ... on line 4 of this example
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment