os.path.basename

basename(p) == split(p)[1] and dirname(p) == split(p)[0]. Unlike the Unix basename command, a trailing slash gives an empty basename: basename('/var/log/') is ''. dirname of a bare file name is '' — not '.'.

os.path functionPython 3.0+Live demo
Common call
os.path.basename(path)
Returns
'main.py'
Replaces
path.split('/')[-1]
Watch out
Trailing slash → ''; dirname('main.py') → ''
os.path.basename(path) / os.path.dirname(path)
→ str

Demo

Live evaluation
Both halves of a POSIX path.
Try:
Inputs
pathstra POSIX path
Code
import posixpath
(posixpath.dirname('/srv/app/main.py'), posixpath.basename('/srv/app/main.py'))
Result
('/srv/app', 'main.py')

For '/var/log/' the last separator is the final character, so the basename is empty and dirname strips the trailing slash: '/var/log'. A bare name has no folder part: dirname is the empty string, which os functions do not accept as '.'. Climbing with dirname ends at '/' for an absolute path and at '' for a relative one.

Parameters

NameTypeRequiredDescription
pathstr | bytes | PathLikeyesAny path. Nothing is checked on disk.

Return value

str — basename: the text after the last separator. dirname: the text before it, without trailing separators (the root stays).

Common patterns

The folder of the running script
Make it absolute first so dirname never returns an empty string.
import os
HERE = os.path.dirname(os.path.abspath(__file__))
File name without extension
basename, then splitext.
import os
stem = os.path.splitext(os.path.basename(path))[0]
Name of a folder given with a trailing slash
normpath removes the trailing separator.
import os
name = os.path.basename(os.path.normpath(folder))

Examples

1. File name and folder
import posixpath (posixpath.basename('/srv/app/main.py'), posixpath.dirname('/srv/app/main.py'))
Returns
('main.py', '/srv/app')
2. Trailing slash
import posixpath (posixpath.basename('/var/log/'), posixpath.dirname('/var/log/'))
Returns
('', '/var/log')
3. No folder part
import posixpath posixpath.dirname('main.py')
Returns
''
4. Two levels up
import posixpath posixpath.dirname(posixpath.dirname('/srv/app/main.py'))
Returns
'/srv'
5. Windows paths need ntpath
import ntpath (ntpath.basename(r'C:\Users\ada\x.txt'), ntpath.dirname(r'C:\Users\ada\x.txt'))
Returns
('x.txt', 'C:\\Users\\ada')
6. …posixpath sees one name
import posixpath posixpath.basename(r'C:\Users\ada\x.txt')
Returns
'C:\\Users\\ada\\x.txt'
7. Strip the slash first
import posixpath posixpath.basename('/var/log/'.rstrip('/'))
Returns
'log'

Pitfalls

1. Expecting the Unix basename command
The shell's basename /var/log/ prints log; Python's returns ''.
basename('/var/log/')
import posixpath
posixpath.basename('/var/log/')
''
normpath first
import posixpath
posixpath.basename(posixpath.normpath('/var/log/'))
'log'
2. Using dirname('file') as a folder
It is '' for a bare file name, and os.listdir('') or os.makedirs('') raise FileNotFoundError.
dirname('data.csv')
import os
try:
    os.listdir(os.path.dirname('data.csv'))
except OSError as e:
    result = type(e).__name__
result
'FileNotFoundError'
or '.'
import os
open('data.csv', 'w').close()
os.listdir(os.path.dirname('data.csv') or '.')
['data.csv']
3. Parsing Windows paths with os.path on Linux
Paths received from Windows machines need ntpath (or PureWindowsPath) on every OS.
posixpath
import posixpath
posixpath.dirname(r'C:\data\in.csv')
''
ntpath
import ntpath
ntpath.dirname(r'C:\data\in.csv')
'C:\\data'

When to use

Use it
  • File name or folder of a str path
Reach for something else
  • Both at once → os.path.split
  • pathlib code → p.name and p.parent
  • The extension → splitext

Notes

CPython impl
posixpath.basename: p[p.rfind('/') + 1:]. dirname: the same cut, then trailing '/' removed unless the head is all slashes
parent vs dirname
PurePath('/var/log/').name is 'log' (pathlib drops trailing slashes when parsing); os.path.basename gives ''

FAQ

os.path.basename(path), or Path(path).name. Without the extension: os.path.splitext(os.path.basename(path))[0], or Path(path).stem.