Created
December 13, 2012 16:00
-
-
Save jathanism/4277417 to your computer and use it in GitHub Desktop.
A decorator to inject a namespace into a function's internal global namespace, and then clean it up when you're done. It can be used with or without an argument.
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
from functools import wraps | |
framework_namespace = {'api_key':"This is the api_key"} | |
def inject_namespace(fn=None, namespace=None): | |
""" | |
Inject a dictionary into the global namespace of the wrapped function | |
and then clean it up afterward. Hacktastic! | |
Credit: http://stackoverflow.com/a/3910211/194311 | |
""" | |
if namespace is None: | |
namespace = {} | |
def real_decorator(fn): | |
@wraps(fn) | |
def wrapper(*args, **kwargs): | |
# Determine which names in framework namespace collide | |
preexistent = [n for n in namespace if n in fn.func_globals] | |
nonexistent = [n for n in namespace if n not in preexistent] | |
# Save any preexisting name's values | |
fn.globals_save = dict((n, fn.func_globals[n]) for n in preexistent) | |
# Temporarily inject namespace | |
fn.func_globals.update(namespace) | |
retval = fn(*args, **kwargs) # Call ``fn`` and save ``retval`` | |
# Cleanup namespace to remove names that didn't exist | |
for name in nonexistent: | |
del fn.func_globals[name] | |
# Restore the values of any names that collided | |
fn.func_globals.update(fn.globals_save) | |
return retval | |
return wrapper | |
# Wrap the wrapped function in the real decorator if it's callable | |
if callable(fn): | |
return real_decorator(fn) | |
return real_decorator | |
# Works with or without arguments. If you dont' specify ``namespace``, then the | |
# default is used. | |
#@inject_namespace | |
@inject_namespace(namespace=framework_namespace) | |
def func(x, y): | |
"""Docstring""" | |
print 'inside func()', locals() | |
try: | |
print 'API KEY', api_key | |
except NameError: | |
print 'NO API KEY FOUND' | |
return x + y |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment