tags:

views:

116

answers:

3

One of the features of my project is to allow users to create their own little .txt file, put it somewhere on their HDD, which can then be used as criteria for a part of my application.

Is there a Fixed, 'generic'(?) path for most OSs that I could use? Or does anyone have any kind of advice or guidance that could help me?

FYI, during development, I've just been using a fixed location (/home/user/Desktop/folder1/"), to which I then specify the filename, in order to complete the path.

+7  A: 

os.path.expanduser is a good start -- a leading ~/ expands to "the user's home directory", which is computer by reasonable heuristics on both Unix-y and Windows systems. Of course, you don't want to put your file in the home directly, but a subdirectory of that (which you'll have to make if not already there) is a reasonable default.

Of course, do allow this setting to be overridden by an environment variable or a command line flag passed to your program, because some platforms are rather finicky about where an application is supposed, by convention, to park such auxiliary data files.

Edit: the OP asks for an example:

Suppose I wanted it in ~/tempfoler/ and the file being passed to it was args1.txt?

I'd suggest locating the exact path through a function such as:

import errno
import os

def getfilepath(filename, foldername='tempfoler', envar='MYAPPDIR'):
  # check for environmental override
  if envar is not None and envar in os.environ:
    dirpath = os.environ[envar]
  else:
    dirpath = '~/%s' % foldername
  # expand and ensure it's a directory
  expanded = os.path.expanduser(dirpath)
  if not os.path.isdir(expanded):
    if os.path.lexists(expanded):
      # we're in dire trouble: the path is a file, not a directory!
      # you could punt to some default value, but I prefer to raise
      # an exception and allow higher levels to deal with this
      raise IOError(errno.EEXISTS, "Path is a file, not a dir", expanded)
    # the following may also raise (permission issues, &c)
    os.makedirs(expanded)
  # now the directory exists, the file may or may not (doesn't matter)
  return os.path.join(expanded, filename)

There are some design choices embedded here -- raise exceptions for all kinds of problems (higher levels may catch them and handle them appropriately, e.g. ask the user for an alternative -- this lower level function couldn't do that properly!), return the path to the file which may or may not exist (thus suitable for both reading an existing file or writing a new one), and so on.

You might also choose to do fewer checks and rely more on automatic exceptions being raised for all kinds of anomalies (or vice versa), I just think this one strikes a reasonable balance (and of course it's easy for you to tweak if you prefer a somewhat different approach to such issues). But the key idea is to always focus on what could go wrong and how it will be dealt with (often by higher-level code, the only proper point for possibly asking the user for alternatives) to make your software robust.

Alex Martelli
Perfect answer. Though, could I possible have a quick example of how to use this? Suppose I wanted it in `~/tempfoler/` and the file being passed to it was `args1.txt`?
day_trader
@_bravado, editing the answer to provide the example you request.
Alex Martelli
Thanks a lot, Alex :)
day_trader
Hey Alex, can I also ask what this `envar` variable is? i don't understand why it's preset to `MYAPPDIR`?
day_trader
@_bravado, envar is an argument with a default value -- where to look in the os environment for a possible override (pass as None when you want no environment variable to override the choice of dirpath). Such flexibility makes it possible to respect a certain platform's particular conventions without necessarily hardcoding them (since the user can override what you do have hardcoded by setting his os environment appropriately).
Alex Martelli
+2  A: 

The wx.StandardPaths module contains methods that return various standard locations in the file system and transparently tries to do "the right thing" under Unix, Mac OS X, and Windows.

Vebjorn Ljosa
A simple choice if you're using wxpython. I wouldn't want to pull in that huge dependency just to get directory names, especially when there are alternatives.
Ryan Ginstrom
A: 

For the copy/paste crowd out there...

import os
file_obj = open(os.path.expanduser('~/yourapp/file.txt'), 'w')

Good luck.

Don Spaulding