Flake
Flake

Reputation: 4497

os.path.dirname(__file__) returns empty

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?

Upvotes: 195

Views: 310357

Answers (8)

Melle
Melle

Reputation: 8357

Since Python 3.4, you can use pathlib to get the file's directory:

from pathlib import Path

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

file_path = curr_dir.joinpath('otherfile.txt')

Edit: To get the current directory use

Path.cwd()

Thanks @Nuno André

Upvotes: 7

Nuno André
Nuno André

Reputation: 5349

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/..')

Upvotes: 0

MohammadArik
MohammadArik

Reputation: 67

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

__file__.split(__file__.split("/")[-1])[0]

Upvotes: -1

Deve
Deve

Reputation: 139

import os.path

dirname = os.path.dirname(__file__) or '.'

Upvotes: 13

RY_ Zheng
RY_ Zheng

Reputation: 3427

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

Upvotes: 10

adnan dogar
adnan dogar

Reputation: 211

can be used also like that:

dirname(dirname(abspath(__file__)))

Upvotes: 9

Mikhail
Mikhail

Reputation: 2929

print(os.path.join(os.path.dirname(__file__))) 

You can also use this way

Upvotes: 6

Sven Marnach
Sven Marnach

Reputation: 601609

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__))

Upvotes: 297

Related Questions