Getting original working directory
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Thu Sep 6 20:17:05 EDT 2007
En Thu, 06 Sep 2007 15:47:02 -0300, rave247 rave247 <rave247 at seznam.cz>
escribi�:
> If I could use os.getcwd() or save the value to some variable before
> calling os.chdir() I would do it, believe me. However I can't because it
> is the part of code where I can't do any changes.
>
> Also I do not agree that such thing is not possible because after python
> script finishes its work, it naturally gets back into the original
> location from where you started the script (in shell you are in the
> original location after script finishes). So this information has to be
> stored somewhere (probably in shell which runs the interpreter) and
> there *must* be a way how to get it. Simply after calling os.chdir()
> the original value doen't disappear, I think it just needs some nice
> hack if python doesn't provide a way how to get it.
The "current directory" is a per-process attribute managed by the OS.
This is the greatest way to successfully remember the previous directory
in a step by step recipe:
- Setup a web service in a trusted server exposing an object implementing
a queue-like interfase. Ensure your application has the right permissions
to access the web service (you may have to open a port thru the firewall).
This part is up to you. The poor man's solution is to use a
SimpleXMLRPCServer daemon - that might be enough for starting, good
because it's a full-Python solution but does not scale very well.
- You will need a unique identifier. See this wikipedia article for some
info <http://en.wikipedia.org/wiki/Globally_Unique_Identifier>. I'll
assume you have a CreateGuid() function available (on Windows you can
install the pywin32 package, get it from sourceforge). (A pid is not
enough for use in a global service like this).
- A few lines of code. Save as remember.py anywhere on your Python path
(maybe lib/site-packages)
<code>
from xmlrpclib import ServerProxy
class Rememberer(object):
_guid = _proxy = _queue = None
def __init__(self, proxy_url):
self.proxy_url = proxy_url
def get_guid(self)
"A GUID to to identify this rememberer"
if self._guid is None:
self._guid = CreateGuid()
return self._guid
guid = property(get_guid)
def get_proxy(self)
"xmlrpc proxy"
if self._proxy is None:
self._proxy = ServerProxy(self.proxy_url)
return self._proxy
proxy = property(get_proxy)
def get_queue(self)
"""A queue object in the remote server, identified by
self.guid"""
if self._queue is None:
self._queue = self.proxy.Queue(self.guid)
queue = property(get_queue)
def push(self, value):
self.queue.push(value)
def peek(self):
return self.queue.peek()
def make_remember(self, function, what_to_remember):
@functools.wraps(function)
def inner(*args, **kw):
self.push(what_to_remember())
function(*args, **kw)
return inner
</code>
- The rememberer is globally accesible thru your url. You can use it with
any process you wish, from anywhere in the world. Just make sure your GUID
creator is good enough - as said on this recent post
<http://groups.google.com/group/comp.lang.python/msg/76e25141b9963dfb>,
you should arrange things to wait some time at system startup until the
system has collected enough bits of entropy to generate a good identifier.
- We are almost ready! The crucial part is to replace os.chdir with a
wrapped version:
<code>
import os, remember
rememberer = remember.Rememberer("your.server.url")
replacements = dict(chdir = ('make_remember', (os.chdir, os.getcwd)),
prevdir = ('peek', None))
for attr, (fn, args) in replacements.iteritems():
if args:
value = getattr(rememberer, fn)(*args)
else:
value = getattr(rememberer, fn)
setattr(os, attr, value)
</code>
Do that as early as possible; I'd put those lines in lib/sitecustomize.py
(create that file if not already there). See
http://docs.python.org/lib/module-site.html for info on the Python
initialization sequence.
- Now, you have a new function os.prevdir() which returns the directory
that was current before the last call to os.chdir. The global web service
holds a full stack of all the previous dirs, and you can extend the
interfase to retrieve any value if you wish. Just remember the GUID used
or you won't be able to retrieve anything.
- Some bits are left as an exercise: there is no provision to remove
items from the queue, no security enforced, and it's not thread safe (is
it?).
- The above code is untested, has no guarantees, standard disclaimers
apply, use at your own risk, etc... Moreover, since all that mess can be
replaced by a simple line like:
original_dir = os.getcwd()
or something similar near the top of your script, I would not even
*attempt* to use it...
--
Gabriel Genellina
PS: Sorry! Could not resist...
More information about the Python-list
mailing list