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.