syntactic sugar for filesystem access in Python
Bjorn Pettersen
bjorn at roguewave.com
Tue Sep 26 20:18:46 EDT 2000
It's irresistably cute, so who cares if it's useful ;-)
-- bjorn
Kragen Sitaker wrote:
>
> It is with some trepidation that I post this; I'm not sure it's
> useful. It provides some very simple filesystem-access functionality
> in a very simple way, but it will throw exceptions at surprising times
> if the filesystem changes underneath it.
>
> Still, it should be entertaining.
>
> From kragen at kirk.dnaco.net Tue Sep 26 19:20:04 2000
> Date: Tue, 26 Sep 2000 19:14:21 -0400 (EDT)
> From: Kragen <kragen at kirk.dnaco.net>
> To: kragen-hacks at kragen.dnaco.net
> Subject: syntactic sugar for filesystem access in Python
>
> Here's a sample session; source code follows:
> [kragen at kragen devel]$ python
> Python 1.5.2 (#1, Sep 17 1999, 20:15:36) [GCC egcs-2.91.66 19990314/Linux (egcs- on linux-i386
> Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
> >>> import filesystem
> >>> fs = filesystem.Filesystem()
> >>> home = fs.home.kragen
> >>> nonexistent = fs.nonexistent_name
> Traceback (innermost last):
> File "<stdin>", line 1, in ?
> File "filesystem.py", line 21, in __getattr__
> raise AttributeError, name
> AttributeError: nonexistent_name
> >>> fs.bin.cat("/home/kragen/imptest.py")
> class Bound:
> def __import__(*args):
> print "importing ", args
> 0
> >>> imptest = str(home["imptest.py"])
> >>> print home["imptest.py"]
> class Bound:
> def __import__(*args):
> print "importing ", args
>
> >>> fs.bin.ls("-l", "/home/kragen/.ncftp")
> total 128
> -rw------- 1 kragen kragen 3958 Jul 17 17:29 firewall
> -rw------- 1 kragen kragen 870 Sep 25 00:11 history
> -rw-rw-r-- 1 kragen kragen 3093 Sep 25 00:11 log
> -rw-r--r-- 1 kragen kragen 415 Sep 20 13:22 prefs
> -rw------- 1 kragen kragen 3261 Sep 25 00:11 trace
> -rw------- 1 kragen kragen 3545 Jul 25 00:32 trace.002455
> -rw------- 1 kragen kragen 4465 Jul 25 15:55 trace.004094
> -rw------- 1 kragen kragen 12074 Jul 29 21:28 trace.004098
> -rw------- 1 kragen kragen 5610 Jul 25 16:35 trace.004938
> -rw------- 1 kragen kragen 3741 Aug 9 11:33 trace.010544
> -rw------- 1 kragen kragen 31031 Aug 6 13:04 trace.013201
> -rw------- 1 kragen kragen 8652 Aug 4 21:04 trace.013235
> -rw------- 1 kragen kragen 4733 Aug 4 21:13 trace.013247
> -rw------- 1 kragen kragen 10140 Aug 4 22:21 trace.013447
> -rw------- 1 kragen kragen 1421 Sep 22 19:40 trace.019487
> -rw-rw-r-- 1 kragen kragen 143 Sep 25 00:11 v3init
> 0
> >>> home[".ncftp"][:]
> [Filesystem('/home/kragen/.ncftp/v3init'), Filesystem('/home/kragen/.ncftp/firewall'), Filesystem('/home/kragen/.ncftp/trace.002455'), Filesystem('/home/kragen/.ncftp/log'), Filesystem('/home/kragen/.ncftp/history'), Filesystem('/home/kragen/.ncftp/trace'), Filesystem('/home/kragen/.ncftp/prefs'), Filesystem('/home/kragen/.ncftp/trace.004094'), Filesystem('/home/kragen/.ncftp/trace.004938'), Filesystem('/home/kragen/.ncftp/trace.004098'), Filesystem('/home/kragen/.ncftp/trace.013201'), Filesystem('/home/kragen/.ncftp/trace.013235'), Filesystem('/home/kragen/.ncftp/trace.013247'), Filesystem('/home/kragen/.ncftp/trace.013447'), Filesystem('/home/kragen/.ncftp/trace.010544'), Filesystem('/home/kragen/.ncftp/trace.019487')]
> >>> home[".ncftp"][0]
> Filesystem('/home/kragen/.ncftp/v3init')
> >>> home[".ncftp"][1]
> Filesystem('/home/kragen/.ncftp/firewall')
> >>> del home["imptest.py"]
> >>> fs.bin.ls("/home/kragen/imptest.py")
> /bin/ls: /home/kragen/imptest.py: No such file or directory
> 256
> >>> imptest
> 'class Bound:\012 def __import__(*args):\012 print "importing ", args\012'
> >>> home["imptest.py"] = imptest
> >>> fs.bin.ls("/home/kragen/imptest.py")
> /home/kragen/imptest.py
> 0
> >>> len(str(home.core))
> 4808704
> >>> del home.core
> >>> home.core
> Traceback (innermost last):
> File "<stdin>", line 1, in ?
> File "filesystem.py", line 21, in __getattr__
> raise AttributeError, name
> AttributeError: core
> >>> home.name()
> '/home/kragen'
> >>> home.dirname()
> '/home'
> >>> home.basename()
> 'kragen'
> >>>
>
> Pretty cool, huh? You can read and write files from the filesystem and
> run external programs more conveniently in Python than in the shell this
> way. Here's the glue code that does the impedance matching between the
> filesystem and Python:
>
> # Import the filesystem into your Python programs. Inspired by some
> # comments by Mike Dierken I didn't completely understand at the time.
>
> # I hereby disclaim any copyright interest in this work, my intent in
> # so doing being to thereby put it in the public domain.
> # Kragen Sitaker <kragen at pobox.com>, 2000-09-26
>
> # There are some correctness problems with this code, having largely to do
> # with things changing out from under you: the current working directory,
> # These are not issues unique to Python, but they aren't there with normal
> # Python code that doesn't expect to deal with a filesystem.
>
> import os, os.path, types, string
>
> class Filesystem:
> def __init__(self, pathname='/'):
> self.__dict__["pathname"] = pathname
> def __getattr__(self, name):
> pathname = os.path.join(self.pathname, name)
> if not os.path.exists(pathname):
> raise AttributeError, name
> return Filesystem(pathname)
> def __len__(self):
> return len(os.listdir(self.pathname))
> def __getslice__(self, start, end):
> return map ((lambda x, self=self: self.__getattr__(x)),
> os.listdir(self.pathname))
> def __getitem__(self, key):
> if not os.path.isdir(self.pathname):
> raise TypeError, "not a directory"
> if type(key) is types.IntType:
> return self.__getattr__(os.listdir(self.pathname)[key])
> else:
> return self.__getattr__(key)
> def __delattr__(self, key):
> pathname = os.path.join(self.pathname, key)
> if os.path.isdir(pathname):
> os.rmdir(pathname)
> elif os.path.exists(pathname):
> os.remove(pathname)
> else:
> # the equivalent to this for ordinary Python objects is not
> # correct English, so I deviate for correctness
> raise AttributeError, "delete nonexistent file"
> def __delitem__(self, name):
> # sorry, we don't support deletion by numeric index :)
> return self.__delattr__(name)
> def __str__(self):
> fh = open(self.pathname, 'r')
> str = fh.read()
> fh.close()
> return str
> # XXX this is inexact; What if
> # Filesystem isn't defined in the namespace where someone tries to
> # eval this?
> def __repr__(self):
> return 'Filesystem(%s)' % repr(self.pathname)
> def name(self):
> return self.pathname
> def dirname(self):
> return os.path.split(self.pathname)[0]
> def basename(self):
> return os.path.split(self.pathname)[1]
> def __call__(self, *args): # this could be improved!
> nargs = list(args)
> nargs.insert(0, self.name())
> return os.system(string.join(nargs))
> def __setattr__(self, name, value): # we unfortunately only support strings
> fh = open(os.path.join(self.pathname, name), 'w')
> fh.write(value)
> fh.close()
> def __setitem__(self, name, value):
> return self.__setattr__(name, value)
>
> --
> <kragen at pobox.com> Kragen Sitaker <http://www.pobox.com/~kragen/>
> Perilous to all of us are the devices of an art deeper than we ourselves
> possess.
> -- Gandalf the Grey [J.R.R. Tolkien, "Lord of the Rings"]
> --
> http://www.python.org/mailman/listinfo/python-list
More information about the Python-list
mailing list