192

I want to get the path of the current directory under which a .py file is executed.

For example a simple file D:\test.py with code:

import os

print os.getcwd()
print os.path.basename(__file__)
print os.path.abspath(__file__)
print os.path.dirname(__file__)

It is weird that the output is:

D:\
test.py
D:\test.py
EMPTY

I am expecting the same results from the getcwd() and path.dirname().

Given os.path.abspath = os.path.dirname + os.path.basename, why

os.path.dirname(__file__)

returns empty?

Honeybear
  • 2,928
  • 2
  • 28
  • 47
Flake
  • 4,377
  • 6
  • 30
  • 29

8 Answers8

295

Because os.path.abspath = os.path.dirname + os.path.basename does not hold. we rather have

os.path.dirname(filename) + os.path.basename(filename) == filename

Both dirname() and basename() only split the passed filename into components without taking into account the current directory. If you want to also consider the current directory, you have to do so explicitly.

To get the dirname of the absolute path, use

os.path.dirname(os.path.abspath(__file__))
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • 17
    note the above comment has a bold where there should be underline on both sides because of markdown formatting. the original answer was changed correctly – watsonic Mar 29 '16 at 01:38
  • 2
    Note that we never have `os.path.dirname(filename) + os.path.basename(filename) == filename` because the directory separator is missing. We rather have: `os.path.join(os.path.dirname(filename), os.path.basename(filename)) == filename` – Jean Paul Oct 31 '17 at 15:08
  • I am confused, should you leave basedir = os.path.abspath(os.path.dirname(__file__)) in your program ? or what do you replace or where to you replace your path like C:\Users\Test\app.db? – 0004 Oct 23 '18 at 03:05
  • @pes04 `__file__` expands to the name of the current file, so you can use a verbatim copy of the code from this answer. – Sven Marnach Oct 23 '18 at 10:01
  • Why I got error ```NameError: name '__file__' is not defined``` – wawawa Apr 14 '20 at 16:33
  • @Cecilia I can only guess, but probalby because you are trying this in an interactive interpreter, where `__file__` doesn't make sense? – Sven Marnach Apr 14 '20 at 19:29
  • Hi @SvenMarnach Yeah I'm using Jupyter Notebook, but ```os.path()``` returns the dir. – wawawa Apr 15 '20 at 08:08
13
import os.path

dirname = os.path.dirname(__file__) or '.'
Community
  • 1
  • 1
Deve
  • 139
  • 1
  • 2
10
os.path.split(os.path.realpath(__file__))[0]

os.path.realpath(__file__)return the abspath of the current script; os.path.split(abspath)[0] return the current dir

RY_ Zheng
  • 3,041
  • 29
  • 36
9

can be used also like that:

dirname(dirname(abspath(__file__)))
Exelian
  • 5,749
  • 1
  • 30
  • 49
adnan dogar
  • 201
  • 2
  • 4
6
print(os.path.join(os.path.dirname(__file__))) 

You can also use this way

Mikhail
  • 2,690
  • 4
  • 28
  • 43
5

Since Python 3.4, you can use pathlib to get the current directory:

from pathlib import Path

# get parent directory
curr_dir = Path(__file__).parent

file_path = curr_dir.joinpath('otherfile.txt')
Melle
  • 7,639
  • 1
  • 30
  • 31
  • `Path(__file__).parent` returns the _file's directory_. To get the _current directory_ (i.e. the directory of the process, not the file) you can use `Path.cwd()`. – Nuno André Feb 17 '23 at 03:39
0

None of the above answers is correct. OP wants to get the path of the current directory under which a .py file is executed, not stored.

Thus, if the path of this file is /opt/script.py...

#! /usr/bin/env python3
from pathlib import Path

# -- file's directory -- where the file is stored
fd = Path(__file__).parent

# -- current directory -- where the file is executed
# (i.e. the directory of the process)
cwd = Path.cwd()

print(f'{fd=} {cwd=}')

Only if we run this script from /opt, fd and cwd will be the same.

$ cd /
$ /opt/script.py
cwd=PosixPath('/') fd=PosixPath('/opt')

$ cd opt
$ ./script.py
cwd=PosixPath('/opt') fd=PosixPath('/opt')

$ cd child
$ ../script.py
cwd=PosixPath('/opt/child') fd=PosixPath('/opt/child/..')
Nuno André
  • 4,739
  • 1
  • 33
  • 46
-1

I guess this is a straight forward code without the os module..

__file__.split(__file__.split("/")[-1])[0]
MohammadArik
  • 71
  • 1
  • 9