How to get an absolute file path in Python
Asked Answered
P

11

1045

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"
Pastose answered 9/9, 2008 at 10:19 Comment(0)
S
1506
>>> 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'
Squilgee answered 9/9, 2008 at 10:21 Comment(8)
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.Pasteurization
@Pasteurization ? 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?Duntson
@Duntson 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.Frazee
@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.Duntson
@Duntson 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?Frazee
@Duntson ...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.Frazee
@MikeS os.getcwd() does not invoke a system call on the full path. It explicitly 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.Duntson
@Duntson 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.Frazee
I
135

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

Indwell answered 24/10, 2014 at 1:5 Comment(5)
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)Pontormo
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 pathMumford
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?Upanchor
Note that resolve() will follow symlinks. If you don't want this, use absolute() instead, which will leave not resolve symlinks.Hydrolysis
If one wants to stay with the legacy os.path library, one can also use os.path.realpath(PATH) to get the same functionality as pathlib.Path(PATH).resolve(). Especially, realpath() also follows symlinks.Pseudonym
A
39
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).

Axle answered 7/3, 2019 at 0:56 Comment(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).Glassworker
A
30

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'
Anthropogeography answered 12/9, 2008 at 6:53 Comment(5)
Too bad they never got a proper filename abstraction module into the stdlib.Asternal
@Torsten Marek: it's a sore and longstanding omission.Greenshank
They did now for Python 3.4: pathlib. See my answer in this thread.Indwell
There are yypos in this answer. It should be from path import Path then Path('mydir/myfile.txt').abspath()Beneficent
There are no typos, you may have been using a different path module. The linked module uses a class named path.Anthropogeography
M
30

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
Maritzamariupol answered 27/12, 2018 at 20:41 Comment(0)
E
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.

Elliotelliott answered 28/2, 2019 at 15:26 Comment(3)
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.Subrogation
this will fail if the script is called from somewhere other than it's current location, for example from the parent folder.Clamper
@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.Elliotelliott
C
15

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.

Caledonian answered 10/3, 2013 at 17:11 Comment(0)
K
10

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

from pathlib import Path

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

print(fpath)
Kinna answered 30/8, 2021 at 14:44 Comment(1)
This answer was given with more detail already by Mad Physicist in 2018.Nowise
G
2

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'

Gabbey answered 8/2, 2022 at 6:20 Comment(0)
U
1

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
Unexpected answered 3/4, 2018 at 21:12 Comment(1)
Identical to the accepted answer, except it arrived 10 years late.Semeiology
M
-1

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
Mickimickie answered 4/7, 2018 at 19:9 Comment(1)
there's no need for a specific platform solution to find the path of an absolute file. I think sticking with Path module is a better idea.Galba

© 2022 - 2024 — McMap. All rights reserved.