gwydion93
gwydion93

Reputation: 1923

Using a relative path for a local variable in Python

I have a local variable in a Python script that creates temporary files using a path in my local C:\<User> folder:

 Output_Feature_Class = "C:\\Users\\<User>\\Documents\\ArcGIS\\Default.gdb\\Bnd_"

However, I want to be able to share this script with others and don't want to have to hardcode a file path for each person using it. I basically want it to go to the same folder but <insert their User Name> example: C:\\TBrown\\Documents\\ArcGIS\Default.gdb\\Bnd_. I cannot seem to get just using

 Output_Feature_Class = "..\\Documents\\ArcGIS\\Default.gdb\\Bnd_"

to work. Is there something I am missing?

Upvotes: 2

Views: 2492

Answers (4)

Mark Ransom
Mark Ransom

Reputation: 308412

To get the user's home directory you can use os.path.expanduser to get a user's home directory.

Output_Feature_Class = os.path.join(os.path.expanduser('~'), "Documents\\ArcGIS\\Default.gdb\\Bnd_")

As mentioned by others, before you do this please consider if this is the best location for these files. Temporary files should be in a location reserved by OS conventions for temporary files.

Upvotes: 0

Evan
Evan

Reputation: 2301

Instead of storing temporary files in a location of your choosing which may or may not exist, why not use the Windows %TEMP% environment variable? If they don't have %TEMP% set, a lot of software wont work.

import os

def set_temp_path(*args):
    if os.name is 'nt':
        temp_path = os.getenv('TEMP')
        if not temp_path:
            raise OSError('No %TEMP% variable is set? wow!')
        script_path = os.path.join(temp_path, *args)
        if not os.path.exists(script_path):
            os.makedirs(script_path)
        return script_path
    elif os.name is 'posix':
        #perform similar operation for linux or other operating systems if desired
        return "linuxpath!"
    else:
        raise OSError('%s is not a supported platform, sorry!' % os.name)

You can use this code for arbitrary temporary file structures for this or any other script:

my_temp_path = set_temp_path('ArcGIS', 'Default.gdb', 'Bnd_')

Which will create all the needed directories for you and return the path for further use in your script.

'C:\\Users\\JSmith\\AppData\\Local\\Temp\\ArcGIS\\Default.gdb\\Bnd_'

This is of course incomplete if you intend on supporting multiple platforms, but this should be straightforward on linux using the global /tmp or /var/temp paths.

Upvotes: 1

Xantium
Xantium

Reputation: 11603

Rather than asking them to input their username, why not use getpass?

For example to get their username:

import getpass
a = getpass.getuser()
Output_Feature_Class = "C:\\Users\\" + a + "\\Documents\\ArcGIS\\Default.gdb\\Bnd_"

If you work on Windows (and this will work for Windows only) the pywin module can find the path to documents:

from win32com.shell import shell, shellcon

a = shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0)

Output_Feature_Class = "{}\\ArcGIS\\Default.gdb\\Bnd_".format(a)

but this is not cross platform. Thanks to martineau for this solution see Finding the user's "My Documents" path for finding Documents path.

Upvotes: 2

sadmicrowave
sadmicrowave

Reputation: 40942

Same answer as @Simon but with string formatting to condense it a bit and not attempt to concatenate strings together:

import getpass

Output_Feature_Class = "C:\\Users\\%s\\Documents\\ArcGIS\\Default.gdb\\Bnd_" % getpass.getuser()

As @Matteo Italia points out, Nothing guarantees you that user profiles are under c:\users, or that the user profile directory is called with the name of the user. So, perhaps addressing it by getting the user's home directory and building the path from there would be more advantageous:

from os.path import expanduser
Output_Feature_Class = "%s\\Documents\\ArcGIS\\Default.gdb\\Bnd_" % expanduser("~")

Update

As @Matteo Italia points out again, there may be cases when the Documents directory is located somewhere else by default. This may help find the path of the Documents of My Documents folder: reference (link)

from win32com.shell import shell
df = shell.SHGetDesktopFolder()
pidl = df.ParseDisplayName(0, None, "::{450d8fba-ad25-11d0-98a8-0800361b1103}")[1]

Output_Feature_Class = "%s\\ArcGIS\\Default.gdb\\Bnd_" % shell.SHGetPathFromIDList(pidl)

Upvotes: 2

Related Questions