1017

Given a path such as "mydir/myfile.txt", how do I find the file's absolute path in Python? E.g. on Windows, I might end up with:

"C:/example/cwd/mydir/myfile.txt"
Marc Compere
  • 290
  • 4
  • 17
izb
  • 50,101
  • 39
  • 117
  • 168

11 Answers11

1477
>>> import os
>>> os.path.abspath("mydir/myfile.txt")
'C:/example/cwd/mydir/myfile.txt'

Also works if it is already an absolute path:

>>> import os
>>> os.path.abspath("C:/example/cwd/mydir/myfile.txt")
'C:/example/cwd/mydir/myfile.txt'
JakeD
  • 2,788
  • 2
  • 20
  • 29
sherbang
  • 15,696
  • 1
  • 22
  • 16
  • 43
    Note: On most platforms, this is equivalent to calling the function `normpath()` as follows: `normpath(join(os.getcwd(), path))`. So if `mydir/myfile.txt` do not under `os.getcwd()`, the absolute path is __not the real path__. – coanor Nov 25 '14 at 04:15
  • 41
    @coanor ? Without an explicit root, `mydir/myfile.txt` implicitly refers to a path inside the current working directory as is therefore equivalent to `./mydir/myfile.txt`. That might not be the path you intended to input, but it seems like the correct interpretation of the path as far as I can tell. Could you elaborate? – jpmc26 Jan 08 '15 at 22:46
  • 2
    @jpmc26 I don't exactly follow coanor, but I would say that (contrary to what I presumed), there is no linkage between the argument to the `abspath` function and a real file. You could give any pathname- non-existent files and directory heirarchies are fine- and abspath will simply resolve the bits of the path (including the parent directory "`..`" element) and return a string. This is just a string computed from the current directory; any correlation to an actual file is accidental, it seems. Try `os.path.abspath("/wow/junk/../blha/hooey")`. It works. – Mike S Sep 12 '18 at 02:01
  • 2
    @MikeS I'm honestly not sure why that would be unexpected behavior. It's absolute *path*, not absolute file or directory. If you want an existence check, call `os.path.exists`. To the contrary, systems like PowerShell that insist on the path existing with the standard path resolution function are a pain to use. – jpmc26 Sep 12 '18 at 03:28
  • 1
    @jpmc26 To assume that a path is just a string that looks like a pathname is not clear at all, and goes counter to how I've been thinking and speaking of pathnames for many years. I quote the Python 3 docs for abspath: "Return a normalized absolutized version of the pathname *path*." Not a"...version of the _string_ *path*". A pathname, as defined by Posix, is "A string that is used to identify a file." The Python docs are explicit about `relpath`: "the filesystem is not accessed to confirm the existence or nature of `path`". If the argument here is obvious, why be explicit for `relpath`? – Mike S Sep 17 '18 at 18:07
  • @jpmc26 ...to further muddy the waters, the Python docs refer to `abspath` as "...equivalent to calling the function normpath() as follows: `normpath(join(os.getcwd(), path))`." which involves a system call, which is a reference to a real location in a filesystem. So again, we have a blending of the idea that "this refers to something (possibly) found on a filesystem" vs. "This is just a string. No identification with actual files (living or deceased) is intended or should be inferred." I think it would have been better to remove the reference to `getcwd()`, and follow `relpath`'s example. – Mike S Sep 17 '18 at 18:14
  • @MikeS `os.getcwd()` does not invoke a system call *on the full path*. It [explicitly](https://docs.python.org/3.7/library/os.html#os.getcwd) just fetches a string from current environment settings. Prepending its value is necessary when the path is relative, e.g. if it's `'./myfile.txt'` or `'../myfile.txt'`. (Note that if `path` is absolute, then the entire result from `getcwd()` is completely discarded, even.) I can think of no reason why fetching part of the environment state would imply that the function involves checking if the complete path exists. – jpmc26 Sep 17 '18 at 20:06
  • 1
    @jpmc26 You are correct, but that's not what I'm claiming. Forget about `getcwd` if you must and reread my post. My point is: the documentation is inaccurate. They readily blend the concept of a pathname being a true pathname vs. it being nothing more than a string that might refer to a pathname in the filesystem. At other places in the documentation they take pains to point out the difference, because there is. Again, the definition of a pathname is not that it's a simple string. The argument to `abspath` is. This is my final comment; apologies for taking your time. – Mike S Sep 18 '18 at 13:05
124

You could use the new Python 3.4 library pathlib. (You can also get it for Python 2.6 or 2.7 using pip install pathlib.) The authors wrote: "The aim of this library is to provide a simple hierarchy of classes to handle filesystem paths and the common operations users do over them."

To get an absolute path in Windows:

>>> from pathlib import Path
>>> p = Path("pythonw.exe").resolve()
>>> p
WindowsPath('C:/Python27/pythonw.exe')
>>> str(p)
'C:\\Python27\\pythonw.exe'

Or on UNIX:

>>> from pathlib import Path
>>> p = Path("python3.4").resolve()
>>> p
PosixPath('/opt/python3/bin/python3.4')
>>> str(p)
'/opt/python3/bin/python3.4'

Docs are here: https://docs.python.org/3/library/pathlib.html

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
twasbrillig
  • 17,084
  • 9
  • 43
  • 67
  • 6
    Very helpful. Using `os.path.abspath()` gave me an error: `AttributeError: 'NoneType' object has no attribute 'startswith'`, using `Path().resolve()` does not with the same relative filepath. (Linux and Python3.4) – NuclearPeon Aug 31 '15 at 16:14
  • 3
    According to my experiment, in window platform, `resolve()` returns full path to you only if it is able to `resolve()` file. But, `os.path.abspath` returns full path to you anyway even the file does not exists. However, in linux, it always return absolute path – Mond Wan Jul 31 '20 at 09:04
  • Why is that when the `Path(__file__)` alone (without the resolve method) is used in a module being imported along with a package, gives the absolute path instead of the relative path? – aderchox Aug 08 '20 at 08:50
  • 1
    Note that `resolve()` will follow symlinks. If you don't want this, use `absolute()` instead, which will leave not resolve symlinks. – BallpointBen Aug 18 '21 at 16:09
35
import os
os.path.abspath(os.path.expanduser(os.path.expandvars(PathNameString)))

Note that expanduser is necessary (on Unix) in case the given expression for the file (or directory) name and location may contain a leading ~/(the tilde refers to the user's home directory), and expandvars takes care of any other environment variables (like $HOME).

benjimin
  • 4,043
  • 29
  • 48
  • 1
    I know this is a rather old answer, but isn't there one command that does all this in one call? Seems like this would be what would make the incoming path the most flexible and hence often needed (at least in my case that's true). – Florian Blume Oct 05 '21 at 10:39
31

Install a third-party path module (found on PyPI), it wraps all the os.path functions and other related functions into methods on an object that can be used wherever strings are used:

>>> from path import path
>>> path('mydir/myfile.txt').abspath()
'C:\\example\\cwd\\mydir\\myfile.txt'
wim
  • 338,267
  • 99
  • 616
  • 750
Tom
  • 42,844
  • 35
  • 95
  • 101
27

Update for Python 3.4+ pathlib that actually answers the question:

from pathlib import Path

relative = Path("mydir/myfile.txt")
absolute = relative.absolute()  # absolute is a Path object

If you only need a temporary string, keep in mind that you can use Path objects with all the relevant functions in os.path, including of course abspath:

from os.path import abspath

absolute = abspath(relative)  # absolute is a str object
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
18

This always gets the right filename of the current script, even when it is called from within another script. It is especially useful when using subprocess.

import sys,os

filename = sys.argv[0]

from there, you can get the script's full path with:

>>> os.path.abspath(filename)
'/foo/bar/script.py'

It also makes easier to navigate folders by just appending /.. as many times as you want to go 'up' in the directories' hierarchy.

To get the cwd:

>>> os.path.abspath(filename+"/..")
'/foo/bar'

For the parent path:

>>> os.path.abspath(filename+"/../..")
'/foo'

By combining "/.." with other filenames, you can access any file in the system.

Lucas Azevedo
  • 1,867
  • 22
  • 39
  • 2
    This is not what was being asked. They asked about a path in relation to the current working directory, which is not the same thing as the script directory, though they may sometimes end up having the same value. – The Elemental of Destruction May 23 '19 at 04:16
  • this will fail if the script is called from somewhere other than it's current location, for example from the parent folder. – Marc Compere Jul 04 '22 at 17:30
  • @MarcCompere no, it won't. The value of `filename` would be different, but once you use `os.path.abspath()` you will get the absolute path for that file regardless of where you calling it from. – Lucas Azevedo Jul 27 '22 at 09:01
16

Today you can also use the unipath package which was based on path.py: http://sluggo.scrapping.cc/python/unipath/

>>> from unipath import Path
>>> absolute_path = Path('mydir/myfile.txt').absolute()
Path('C:\\example\\cwd\\mydir\\myfile.txt')
>>> str(absolute_path)
C:\\example\\cwd\\mydir\\myfile.txt
>>>

I would recommend using this package as it offers a clean interface to common os.path utilities.

10

You can use this to get absolute path of a specific file.

from pathlib import Path

fpath = Path('myfile.txt').absolute()

print(fpath)
Dhia Shalabi
  • 1,332
  • 1
  • 13
  • 29
3

Given a path such as mydir/myfile.txt, how do I find the file's absolute path relative to the current working directory in Python?

I would do it like this,

import os.path
os.path.join( os.getcwd(), 'mydir/myfile.txt' )

That returns '/home/ecarroll/mydir/myfile.txt'

Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
2

if you are on a mac

import os
upload_folder = os.path.abspath("static/img/users")

this will give you a full path:

print(upload_folder)

will show the following path:

>>>/Users/myUsername/PycharmProjects/OBS/static/img/user
chikwapuro
  • 1,328
  • 1
  • 9
  • 10
0

In case someone is using python and linux and looking for full path to file:

>>> path=os.popen("readlink -f file").read()
>>> print path
abs/path/to/file
BND
  • 612
  • 1
  • 13
  • 23