Last active
December 27, 2017 10:24
-
-
Save dustinvtran/e46f35842ba59d868a8985a0134d04cd to your computer and use it in GitHub Desktop.
Context managers as namespaces. From "Don't Do This" by Richard Jones (https://www.youtube.com/watch?v=H2yfXnUb1S4)
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
import inspect | |
class LocalsCapture(object): | |
def __enter__(self): | |
caller_frame = inspect.currentframe().f_back | |
self.local_names = set(caller_frame.f_locals) | |
return self | |
def __exit__(self, exc_type, exc_val, exc_tb): | |
caller_frame = inspect.currentframe().f_back | |
for name in caller_frame.f_locals: | |
if name not in self.local_names: | |
self.capture(name, caller_frame.f_locals[name]) | |
class capture_in(LocalsCapture): | |
def __init__(self, namespace): | |
self.namespace = namespace | |
def capture(self, name, value): | |
self.namespace[name] = value | |
class capture_on(LocalsCapture): | |
def __init__(self, object): | |
self.object = object | |
def capture(self, name, value): | |
self.object.__dict__[name] = value | |
class capture_globals(capture_in): | |
def __init__(self): | |
caller_frame = inspect.currentframe().f_back | |
super(capture_globals, self).__init__(caller_frame.f_globals) | |
d = {} | |
with capture_in(d): | |
spam = 'ham' | |
print(d) | |
# {'spam': 'ham'} | |
class T(object): | |
def __init__(self): | |
with capture_on(self): | |
spam = 'spam' | |
ham = 'ham' | |
t = T() | |
print(t.spam) | |
# 'spam' | |
def foo(): | |
with capture_globals(): | |
spam = 'ham' | |
print(spam) | |
foo() | |
# 'ham' | |
print(spam) | |
# 'ham' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment