# No matter what the os/path format is, extract the file name from the path.

## Problem

Which Python module can I use to extract filenames from paths, regardless of what operating system I’m using or what path format I’m using?

For example, I’d like c: to be returned by all of these pathways.

a/b/c/
a/b/c
\a\b\c
\a\b\c\
a\b\c
a/b/../../a/b/c/
a/b/../../a/b/c


## Solution #1

In fact, there’s a function that does exactly what you’re looking for.

import os
print(os.path.basename(your_path))


WARNING: When using os.path.basename() to get the base name from a Windows styled path (e.g. “C:myfile.txt”) on a POSIX system, the complete path will be returned.

Below is an example of an interactive Python shell on a Linux host:

Python 3.8.2 (default, Mar 13 2020, 10:14:16)
[GCC 9.3.0] on linux
>>> import os
>>> filepath = "C:\\my\\path\\to\\file.txt" # A Windows style file path.
>>> os.path.basename(filepath)
'C:\\my\\path\\to\\file.txt'


## Solution #2

Using os.path.split or os.path.basename as others suggest won’t work in all cases: if you’re running the script on Linux and attempt to process a classic windows-style path, it will fail.

The path separator in Windows paths can be either a backslash or a forward slash. As a result, on all systems, the ntpath module (which is similar to os.path on Windows) will function for all(1) paths.

import ntpath
ntpath.basename("a/b/c")


Naturally, if the file ends in a slash, the basename will be empty, so create your own method to handle it:

def path_leaf(path):


Verification:

>>> paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c',
...     'a/b/../../a/b/c/', 'a/b/../../a/b/c']
>>> [path_leaf(path) for path in paths]
['c', 'c', 'c', 'c', 'c', 'c', 'c']


(1) One caveat: filenames on Linux may contain backslashes. As a result, on Linux, r’a/bc’ always refers to the file bc in the a folder, whereas on Windows, it always refers to the c file in the a folder’s b subdirectory. When a path contains both forward and backward slashes, you must know the platform associated with it in order to understand it correctly. In reality, it’s safe to presume it’s a Windows path because backslashes are rarely used in Linux filenames, but keep this in mind while writing code to avoid creating security flaws by accident.

## Solution #3

The function you’re looking for is os.path.split.

head, tail = os.path.split("/tmp/d/a.dat")

>>> print(tail)
a.dat
/tmp/d


## Solution #4

In python 3

>>> from pathlib import Path
>>> Path("/tmp/d/a.dat").name
'a.dat'


## Solution #5

import os