Python context managers: they are easy!
This comes from this thread in the Python Argentina mailing list (which I strongly recommend if you read spanish).
I was the other day trying to do shell-script-like-things on python (as part of a monster setup.py) and I was annoyed that in shell it's easy to do this:
cd foo
bar -baz
cd -
Or this:
pushd foo
bar -baz
popd
Or this:
(cd foo && bar -baz)
And on Python I had to do this, which is verbose and ugly:
cwd = os.getcwd()
try:
os.chdir('foo')
os.system('bar -baz')
finally:
os.chdir(cwd)
This is what I wanted to have:
with os.chdir('foo'):
os.system('bar -baz')
And of course, you can't do that. So, I asked, how do you implement that context manager? I got several answers.
-
That's available in Fabric:
with cd("foo"): run("bar")
-
It's not hard to do:
class DirContextM(object): def __init__(self, new_dir): self.new_dir = new_dir self.old_dir = None def __enter__(self): self.old_dir = os.getcwd() os.chdir(self.new_dir) def __exit__(self, *_): os.chdir(self.old_dir)
-
It's even easier to do:
from contextlib import contextmanager @contextmanager def cd(path): old_dir = os.getcwd() os.chdir(path) yield os.chdir(old_dir)
That's cool, so let's add it to path.py
-
Maybe check for exceptions
@contextmanager def cd(path): old_dir = os.getcwd() os.chdir(path) try: yield finally: os.chdir(old_dir)
All in all, I learned how to do context managers, about contextlib, about fabric and about path.py. Which is not bad for 15 minutes :-)
stackoverflow.com is also useful for such issues:
http://stackoverflow.com/qu...
Used in fabric: http://docs.fabfile.org/en/...
I’ve been using the shell for, like, six years, and I’ve never heard of `cd -`. This is going to save me some typing over the next six years. Thank you.
`cd -` is equivalent to `cd $OLDPWD` (the variable is managed by the shell), so you are not restricted to moving back to the previous directory; you can also do stuff like: `mv misplaced-file $OLDPWD`
I tend to use the dirstack a little differently. Sometimes cd - can take you strange places. But then again, popd'ing a few directories can also lead you astray.