Created
July 20, 2019 22:10
-
-
Save JimDennis/08e1c32aa6b095b8456526128ab36279 to your computer and use it in GitHub Desktop.
Example of a naïve decorator function
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 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__ | |
## 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