pathlib module, introduced in Python 3.4 (PEP 428 — The pathlib module — object-oriented filesystem paths), makes path-related experience much much better.
$ pwd
/home/skovorodkin/stack
$ tree
.
└── scripts
├── 1.py
└── 2.py
In order to get current working directory use Path.cwd():
from pathlib import Path
print(Path.cwd()) # /home/skovorodkin/stack
To get an absolute path to your script file, use Path.resolve() method:
print(Path(__file__).resolve()) # /home/skovorodkin/stack/scripts/1.py
And to get path of a directory where your script is located, access .parent (it is recommended to call .resolve()
before .parent
):
print(Path(__file__).resolve().parent) # /home/skovorodkin/stack/scripts
Remember that __file__
is not reliable in some situations: How do I get the path of the current executed file in Python?.
Please note, that Path.cwd()
, Path.resolve()
and other Path
methods return path objects (PosixPath in my case), not strings. In Python 3.4 and 3.5 that caused some pain, because open built-in function could only work with string or bytes objects, and did not support Path
objects, so you had to convert Path
objects to strings or use Path.open() method, but the latter option required you to change old code:
$ cat scripts/2.py
from pathlib import Path
p = Path(__file__).resolve()
with p.open() as f: pass
with open(str(p)) as f: pass
with open(p) as f: pass
print('OK')
$ python3.5 scripts/2.py
Traceback (most recent call last):
File "scripts/2.py", line 11, in <module>
with open(p) as f:
TypeError: invalid file: PosixPath('/home/skovorodkin/stack/scripts/2.py')
As you can see open(p)
does not work with Python 3.5.
PEP 519 — Adding a file system path protocol, implemented in Python 3.6, adds support of PathLike objects to open function, so now you can pass Path
objects to open
function directly:
$ python3.6 scripts/2.py
OK