I do agree, the making a context manager, just to get a throw-away instance is really ugly.
I do like the ability to have a manager that will do auto-cleanup, but if you use the class without it, being able to cleanup after yourself manually, open being a good example of this.
So I really should have setup the context manager more like:
import os
class SetEnv(object):
def __init__(self, key, value):
self._key = key
os.environ[key] = value
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.cleanup()
return False
def cleanup(self):
os.environ.pop(self._key)
print(os.environ.get('SomeKey', 'No key named SomeKey'))
# No key named SomeKey
with SetEnv('SomeKey', 'SomeValue'):
print(os.environ.get('SomeKey', 'No key named SomeKey'))
# SomeValue
print(os.environ.get('SomeKey', 'No key named SomeKey'))
# No key named SomeKey
changed_env = SetEnv('SomeKey', 'SomeValue')
print(os.environ.get('SomeKey', 'No key named SomeKey'))
# SomeValue
changed_env.cleanup()
print(os.environ.get('SomeKey', 'No key named SomeKey'))
# No key named SomeKey
I can’t figure out a clean way to do have a similar system off of the contextmanager decorator though, I get some really weird behavior by calling next manually multiple times. It seems to silently stop the execution flow somehow.
Pymel and mGui’s layout classes are good examples of adding optional functionality with context managers. You can handle the parent stack using the context managers, or if you just want to create a new layout and manually parent it, you can.