1415

How do I get the current file's directory path? I tried:

>>> os.path.abspath(__file__)
'C:\\python27\\test.py'

But I want:

'C:\\python27\\'
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Shubham
  • 21,300
  • 18
  • 66
  • 89
  • 14
    `__file__` is not defined when you run python as an interactive shell. The first piece of code in your question looks like it's from an interactive shell, but would actually produce a `NameError`, at least on python 2.7.3, but others too I guess. – drevicko May 31 '15 at 01:04
  • 4
    Why. is. this. so. hard. There are like a dozen SO threads on this topic. Python: "Simple is better than complex...There should be one-- and preferably only one --obvious way to do it." – eric Feb 03 '21 at 03:38
  • os.path.split(file_path)[0] – Super Mario Nov 22 '22 at 15:28
  • 1
    @eric it isn't hard, and the existence of multiple questions isn't evidence of something being hard - it's evidence of people not doing good research, of question titles being suboptimal for SEO, and/or of people failing to close duplicates that should be closed. – Karl Knechtel Jan 18 '23 at 10:44

12 Answers12

2646

The special variable __file__ contains the path to the current file. From that we can get the directory using either pathlib or the os.path module.

Python 3

For the directory of the script being run:

import pathlib
pathlib.Path(__file__).parent.resolve()

For the current working directory:

import pathlib
pathlib.Path().resolve()

Python 2 and 3

For the directory of the script being run:

import os
os.path.dirname(os.path.abspath(__file__))

If you mean the current working directory:

import os
os.path.abspath(os.getcwd())

Note that before and after file is two underscores, not just one.

Also note that if you are running interactively or have loaded code from something other than a file (eg: a database or online resource), __file__ may not be set since there is no notion of "current file". The above answer assumes the most common scenario of running a python script that is in a file.

References

  1. pathlib in the python documentation.
  2. os.path - Python 2.7, os.path - Python 3
  3. os.getcwd - Python 2.7, os.getcwd - Python 3
  4. what does the __file__ variable mean/do?
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • 61
    abspath() is mandatory if you do not want to discover weird behaviours on windows, where dirname(__file__) may return an empty string! – sorin Oct 25 '11 at 10:10
  • 4
    should be os.path.dirname(os.path.abspath(os.__file__))? – DrBailey Mar 27 '14 at 12:28
  • 1
    @drbailey: no. What makes you think that it should? – Bryan Oakley Mar 27 '14 at 12:48
  • @BryanOakley __file__ is not defined, though perhaps this is unique to ActivePython installs? – DrBailey Apr 17 '14 at 19:57
  • 6
    @DrBailey: no, there's nothing special about ActivePython. `__file__` (note that it's two underscores on either side of the word) is a standard part of python. It's not available in C-based modules, for example, but it should always be available in a python script. – Bryan Oakley Apr 17 '14 at 21:32
  • 12
    I would recommend using realpath instead of abspath to resolve a possible symbolic link. – TTimo Jan 09 '15 at 21:37
  • 1
    In Windows Powershell you may need quotation marks around __file__ i.e. `"__file__"` – cph2117 Aug 11 '16 at 21:28
  • @cph2117: I'm not sure what you mean. I don't think powershell changes how `os.path.abspath` works. – Bryan Oakley Aug 11 '16 at 21:54
  • It may not be a function of powershell, but when I tried without the quotations it threw an error saying that __file__ is not defined – cph2117 Aug 11 '16 at 21:56
  • 17
    @cph2117: this will only work if you run it in a script. There is no `__file__` if running from an interactive prompt. \ – Bryan Oakley Aug 11 '16 at 21:57
  • @BryanOakley that makes more sense given that the output was the root python directory :) – cph2117 Aug 11 '16 at 21:58
  • and to use both (works both as script and in the interactive python shell): `try:` `path = os.path.dirname(os.path.abspath(__file__))` `except Exception:` `path = os.getcwd()` (with proper indentation) – Michal Skop Dec 01 '17 at 03:32
  • `'__file__'` should work in both interactive prompts and basic running. – Artemis May 23 '18 at 20:12
  • @ArtemisFowl: have you actually tried it in an interactive prompt? `__file__` will not be set since there is no file. What do you think it would be set to? – Bryan Oakley May 23 '18 at 20:23
  • @BryanOakley It was a string. – Artemis May 23 '18 at 20:26
  • When I run ptyhon from emacs using `C-c, C-c`; `os.path.abspath(os.getcwd())` returns the parent base folder @Bryan Oakley – alper Mar 09 '20 at 15:45
  • @alper: I'm not sure I understand your comment. `os.path.abspath(os.getcwd())` will always return the absolute path to the current working directory. It doesn't matter if you run it from emacs, IDLE, eclipse, or anything else. – Bryan Oakley Mar 09 '20 at 16:19
  • When I run my code through script (`python run.py`) it returns its absolute path, but when I run inside `emacs` its returns the base folder, instead of the absolute path. Maybe I have current setup (https://stackoverflow.com/a/50194143/2402577) it may be the reason for it @Bryan Oakley – alper Mar 09 '20 at 16:38
  • hmm...I'm getting " NameError: name '__file__' is not defined" – ScottyBlades May 12 '20 at 13:19
  • 1
    @ScottyBlades did you see the last paragraph of the answer? – Bryan Oakley May 12 '20 at 14:11
  • I’m running code from a file, not loading it. What does interactively mean here? – ScottyBlades May 12 '20 at 15:11
  • 1
    ```pathlib.Path('__file__').parent.absolute()``` – Javi Sep 22 '20 at 15:01
  • @Javi: you definitely shouldn't put `__file__` in quotes. That turns it from the filename of the current file to the literal 8-byte string `"__file__"` – Bryan Oakley Sep 22 '20 at 15:04
  • 2
    Use the Path.resolve method (https://docs.python.org/3/library/pathlib.html#pathlib.Path.resolve) instead of the Path.absolute method, which is undocumented. – iMineLink Feb 23 '21 at 14:19
  • to access the string name itself, use the as_posix() method, as: pathlib.Path(__file__).parent.absolute().as_posix() and respectively pathlib.Path().absolute().as_posix() – alex May 27 '21 at 01:22
  • @sorin does this still happen? If so, do you have any references? – sourcream Jun 28 '22 at 15:00
  • @NikolaiEhrhardt: this works for me, are you saying it doesn't work for you? `python -c 'import os; print(os.path.abspath("/tmp"))'` – Bryan Oakley Aug 28 '22 at 17:59
  • Don't forget that you can go to the parent directory without having to use the `.parent` method, you may concatenate: `__file__ + "/.."` (two dots indicate the parent directory). – Keyacom Nov 16 '22 at 21:50
  • What does `.resolve()` do? The output seems to be the same without it. – stefanbschneider Jan 17 '23 at 07:58
  • 1
    @CGFoX: here's the documentation for resolve: https://docs.python.org/3/library/pathlib.html#pathlib.Path.resolve – Bryan Oakley Jan 17 '23 at 15:06
191

Using Path from pathlib is the recommended way since Python 3:

from pathlib import Path
print("File      Path:", Path(__file__).absolute())
print("Directory Path:", Path().absolute()) # Directory of current working directory, not __file__  

Note: If using Jupyter Notebook, __file__ doesn't return expected value, so Path().absolute() has to be used.

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Ron Kalian
  • 3,280
  • 3
  • 15
  • 23
  • 31
    I had to do `Path(__file__).parent` to get the folder that is containing the file – YellowPillow Jun 06 '18 at 04:09
  • That is correct @YellowPillow, `Path(__file__)` gets you the file. `.parent` gets you one level above ie the containing directory. You can add more `.parent` to that to go up as many directories as you require. – Ron Kalian Jun 06 '18 at 08:18
  • 1
    Sorry I should've have made this clearer, but if `Path().absolute()` exists in some module located at `path/to/module` and you're calling the module from some script located at `path/to/script` then would return `path/to/script` instead of `path/to/module` – YellowPillow Jun 06 '18 at 12:22
  • 1
    @YellowPillow `Path(__file__).cwd()` is more explicit – C.W. Feb 08 '19 at 16:00
  • 3
    `Path(__file__)` doesn't always work, for example, it doesn't work in Jupyter Notebook. `Path().absolute()` solves that problem. – Ron Kalian Feb 08 '19 at 16:09
  • `Path(__file__)` worked in IDLE but when I used it in a python script that is executed from cmdline it would only return the name of script w/o its parents... strange...is there a bug? I had to use `Path(__file__).absolute()` as you had mentioned to reveal the full path. Occurred in python 3.6. Btw, I did not find the `.absolute()` method described in Python3.6 documentation. – Sun Bear Oct 12 '19 at 14:45
  • Above comment was for a file. To get the file's parent directory, `Path().absolute()` and `Path(__file__).absolute().parent` gave the same result in Python3.6. – Sun Bear Oct 12 '19 at 15:07
  • @SunBear what if you change the working directory to a different directory than the file? – NotAnAmbiTurner Feb 10 '21 at 05:33
  • @NotAnAmbiTurner I don't quite understand your question. Suggest u post a question. If it helps, `Path.cwd()` always returns the current working directory. – Sun Bear Feb 10 '21 at 14:09
  • for wiw; `Path(__file__).absolute().parent` in the interactive terminal returns `Traceback (most recent call last): File "", line 1, in NameError: name '__file__' is not defined ` but specifically adding the file string seems to work. Example: `Path('__file__').absolute().parent` returns `PosixPath('/Users/.../.../foldername')` – JayRizzo Jun 01 '22 at 17:39
104

In Python 3.x I do:

from pathlib import Path

path = Path(__file__).parent.absolute()

Explanation:

  • Path(__file__) is the path to the current file.
  • .parent gives you the directory the file is in.
  • .absolute() gives you the full absolute path to it.

Using pathlib is the modern way to work with paths. If you need it as a string later for some reason, just do str(path).

Arminius
  • 2,363
  • 1
  • 18
  • 22
  • 9
    This should be the accepted answer as of 2019. One thing could be mentioned in the answer as well: one can immediately call `.open()` on such a `Path` object as in `with Path(__file__).parent.joinpath('some_file.txt').open() as f:` – stefanct Aug 02 '19 at 15:20
  • The other issue with some of the answers (like the one from Ron Kalian, if I'm not mistaken), is that it will give you the current directory, not necessarily the __file__ path. – NotAnAmbiTurner Feb 10 '21 at 05:23
20

Try this:

import os
dir_path = os.path.dirname(os.path.realpath(__file__))
Akshaya Natarajan
  • 1,865
  • 15
  • 17
17
import os
print(os.path.dirname(__file__))
JayRizzo
  • 3,234
  • 3
  • 33
  • 49
chefsmart
  • 6,873
  • 9
  • 42
  • 47
7

I found the following commands return the full path of the parent directory of a Python 3 script.

Python 3 Script:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from pathlib import Path

#Get the absolute path of a Python3.6 and above script.
dir1 = Path().resolve()  #Make the path absolute, resolving any symlinks.
dir2 = Path().absolute() #See @RonKalian answer 
dir3 = Path(__file__).parent.absolute() #See @Arminius answer
dir4 = Path(__file__).parent 

print(f'dir1={dir1}\ndir2={dir2}\ndir3={dir3}\ndir4={dir4}')

REMARKS !!!!

  1. dir1 and dir2 works only when running a script located in the current working directory, but will break in any other case.
  2. Given that Path(__file__).is_absolute() is True, the use of the .absolute() method in dir3 appears redundant.
  3. The shortest command that works is dir4.

Explanation links: .resolve(), .absolute(), Path(file).parent().absolute()

Sun Bear
  • 7,594
  • 11
  • 56
  • 102
  • 1
    A bare ``Path()`` does *not* provide the script/module directory. It is equivalent to ``Path('.')`` – the *current working* directory. This is equivalent only when running a script located in the current working directory, but will break in any other case. – MisterMiyagi Oct 15 '21 at 08:47
  • @MisterMiyagi I have updated your comment to my answer. Thanks. – Sun Bear Oct 15 '21 at 16:13
4

works also if __file__ is not available (jupyter notebooks)

import sys
from pathlib import Path
path_file = Path(sys.path[0])
print(path_file)

Also uses pathlib, which is the object oriented way of handling paths in python 3.

Markus Dutschke
  • 9,341
  • 4
  • 63
  • 58
3

USEFUL PATH PROPERTIES IN PYTHON:

from pathlib import Path

#Returns the path of the current directory
mypath = Path().absolute()
print('Absolute path : {}'.format(mypath))

#if you want to go to any other file inside the subdirectories of the directory path got from above method
filePath = mypath/'data'/'fuel_econ.csv'
print('File path : {}'.format(filePath))

#To check if file present in that directory or Not
isfileExist = filePath.exists()
print('isfileExist : {}'.format(isfileExist))

#To check if the path is a directory or a File
isadirectory = filePath.is_dir()
print('isadirectory : {}'.format(isadirectory))

#To get the extension of the file
fileExtension = mypath/'data'/'fuel_econ.csv'
print('File extension : {}'.format(filePath.suffix))

OUTPUT: ABSOLUTE PATH IS THE PATH WHERE YOUR PYTHON FILE IS PLACED

Absolute path : D:\Study\Machine Learning\Jupitor Notebook\JupytorNotebookTest2\Udacity_Scripts\Matplotlib and seaborn Part2

File path : D:\Study\Machine Learning\Jupitor Notebook\JupytorNotebookTest2\Udacity_Scripts\Matplotlib and seaborn Part2\data\fuel_econ.csv

isfileExist : True

isadirectory : False

File extension : .csv

Arpan Saini
  • 4,623
  • 1
  • 42
  • 50
  • Thx. Works also perfect in JupyterLab – Nils B Jul 21 '20 at 18:51
  • 5
    this is misleading absolute is cwd not where your file is placed. not guaranteed to be the same. – eric Feb 03 '21 at 03:43
  • 3
    ``Path()`` is the current working directory, not the directory of the script. This only "works" in the few cases where the script actually is in the current working directory. – MisterMiyagi Oct 15 '21 at 08:48
1

Python 2 and 3

You can simply also do:

from os import sep
print(__file__.rsplit(sep, 1)[0] + sep)

Which outputs something like:

C:\my_folder\sub_folder\
Giorgos Xou
  • 1,461
  • 1
  • 13
  • 32
  • On a `windows 7` machine with `python3.8.10` that I just tested it , for some reason `__file__` doesn't seem to return any path but only just the file-name. Just saying in case anyone else ... – Giorgos Xou Sep 06 '22 at 11:50
0

IPython has a magic command %pwd to get the present working directory. It can be used in following way:

from IPython.terminal.embed import InteractiveShellEmbed

ip_shell = InteractiveShellEmbed()

present_working_directory = ip_shell.magic("%pwd")

On IPython Jupyter Notebook %pwd can be used directly as following:

present_working_directory = %pwd
Nafeez Quraishi
  • 5,380
  • 2
  • 27
  • 34
  • 8
    The question isn't about IPython – Kiro Apr 10 '18 at 08:07
  • 3
    @Kiro, my solution *answers the question* using IPython. For example If some one answers a question with a solution using a new library then also imho it remains a pertinent answer to the question. – Nafeez Quraishi Apr 11 '18 at 09:36
  • @NafeezQuraishi your solution introduces a third party library, and a class from which you have to instantiate in order to achieve the desired result. Myself, and I think many others try to avoid using external libraries for a number of reasons, and I would only try your solution if nothing else worked. Luckily, there's a series of built in functions you can use to get the desired result, and without the need of an external library. – elliotwesoff Sep 03 '19 at 22:54
  • 2
    @elli0t, partially agree. Consider someone using Jupyter notebook has this question for whom perhaps using %pwd magic command would be easier and preferable over os import. – Nafeez Quraishi Sep 10 '19 at 12:27
  • 1
    The question isn't about getting the present working directory, it's about getting the directory of the script. Those two can be very different things. – Bryan Oakley Feb 03 '21 at 04:10
  • current file in question indicates current/present working dir – Nafeez Quraishi Feb 03 '21 at 04:29
  • 5
    @NafeezQuraishi: I don't know what you mean. The question is clearly asking about the path to the directory that the file is in, which may not be the current working directory. Those are two different concepts. – Bryan Oakley Feb 03 '21 at 15:38
  • @BryanOakley. Ahh, i see. Yes agree these can be two different things. Thanks! – Nafeez Quraishi Feb 03 '21 at 16:26
0

I have made a function to use when running python under IIS in CGI in order to get the current folder:

import os 
def getLocalFolder():
    path=str(os.path.dirname(os.path.abspath(__file__))).split(os.sep)
    return path[len(path)-1]
MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
Gil Allen
  • 1,169
  • 14
  • 24
0

This can be done without a module.

def get_path():
    return (__file__.replace(f"<your script name>.py", ""))
print(get_path())
Charlie
  • 21
  • 4