How to Get Filename From Path in Python

To get the filename from a path in Python, use Path(path).name from pathlib or os.path.basename(path). Both return the last part, such as sales_q3_2026.csv; use Path(path).stem for the name without its extension:

from pathlib import Path
Path(r"C:\Reports\2026\sales_q3_2026.csv").name   # 'sales_q3_2026.csv'

Windows and Linux paths split differently, so I say which one applies where it matters; my runs were on Windows with Python 3.12.5.

You’ll see Path.name and os.path.basename side by side, the name without the extension, the trailing-slash difference, Windows paths on Linux, file names from URLs, and a folder example.

Get the filename from a path with Path.name and os.path.basename()

For a normal file path they give the same answer. pathlib also hands you the pieces around it:

import os
from pathlib import Path

path = r"C:\Reports\2026\sales_q3_2026.csv"

print(os.path.basename(path))
print(Path(path).name)
print(Path(path).stem, "|", Path(path).suffix)
print(os.path.dirname(path), "|", Path(path).parent)
print(os.path.split(path))

Output:

sales_q3_2026.csv
sales_q3_2026.csv
sales_q3_2026 | .csv
C:\Reports\2026 | C:\Reports\2026
('C:\\Reports\\2026', 'sales_q3_2026.csv')
Command Prompt output of Python os.path.basename and pathlib Path.name returning the file name from a Windows path
Both return sales_q3_2026.csv; stem and suffix split it into the name and .csv, and dirname gives the folder.

os.path.split() returns the folder and basename together. To read the file once you have it, see reading a file into an array in Python.

Get the filename without the extension

stem drops only the last extension, which matters for names like .sql.gz. suffixes lists all of them:

from pathlib import Path

for p in [r"C:\Reports\2026\sales_q3_2026.csv", "backups/db_2026-10-06.sql.gz", "notes/README", ".env"]:
    path = Path(p)
    print(f"{path.name:<22} stem={path.stem!r:<20} suffix={path.suffix!r:<6} suffixes={path.suffixes}")

archive = Path("backups/db_2026-10-06.sql.gz")
print("all extensions removed:", archive.name.removesuffix("".join(archive.suffixes)))

Output:

sales_q3_2026.csv      stem='sales_q3_2026'      suffix='.csv' suffixes=['.csv']
db_2026-10-06.sql.gz   stem='db_2026-10-06.sql'  suffix='.gz'  suffixes=['.sql', '.gz']
README                 stem='README'             suffix=''     suffixes=[]
.env                   stem='.env'               suffix=''     suffixes=[]
all extensions removed: db_2026-10-06
Command Prompt output of Python pathlib stem, suffix and suffixes for file names with one, two and no extensions
sales_q3_2026.csv gives the stem sales_q3_2026, the .sql.gz backup keeps .sql in its stem, and .env has no suffix at all.

Dotfiles like .env count as a name with no extension. For the extension itself, see getting the file extension from a file name.

Why does os.path.basename return an empty filename?

os.path.basename() returns whatever follows the last separator. If the path ends in a slash, that’s nothing. Path.name normalizes the path first:

import os
from pathlib import Path

for p in ["exports/invoices", "exports/invoices/", "exports/invoices.zip", "", "."]:
    print(f"{p!r:<24} basename={os.path.basename(p)!r:<16} Path.name={Path(p).name!r}")

folder = "exports/invoices/"
print("fixed:", os.path.basename(os.path.normpath(folder)))

Output:

'exports/invoices'       basename='invoices'       Path.name='invoices'
'exports/invoices/'      basename=''               Path.name='invoices'
'exports/invoices.zip'   basename='invoices.zip'   Path.name='invoices.zip'
''                       basename=''               Path.name=''
'.'                      basename='.'              Path.name=''
fixed: invoices
Command Prompt output comparing Python os.path.basename and Path.name on folder paths with and without a trailing slash
With a trailing slash, basename returns an empty string while Path.name still returns invoices.

Wrap the path in os.path.normpath() to fix it, or just use pathlib. For the folder itself, checking if a directory exists is often the next step.

Get the filename from a Windows path on Linux (and vice versa)

os.path follows the OS the code runs on. A Windows path read on Linux, say from a database or an upload form, keeps its backslashes. Use ntpath or PureWindowsPath to parse it explicitly:

import ntpath
import posixpath
from pathlib import PurePosixPath, PureWindowsPath

win = r"C:\Users\Public\Documents\budget_2026.xlsx"
nix = "/home/emily/backups/db_2026-10-06.sql.gz"

print("posixpath on a Windows path:", posixpath.basename(win))
print("ntpath on a Windows path:   ", ntpath.basename(win))
print("PureWindowsPath:            ", PureWindowsPath(win).name)
print("PurePosixPath:              ", PurePosixPath(nix).name)
print("ntpath on a Linux path:     ", ntpath.basename(nix))
print("suffixes:", PurePosixPath(nix).suffixes)

Output:

posixpath on a Windows path: C:\Users\Public\Documents\budget_2026.xlsx
ntpath on a Windows path:    budget_2026.xlsx
PureWindowsPath:             budget_2026.xlsx
PurePosixPath:               db_2026-10-06.sql.gz
ntpath on a Linux path:      db_2026-10-06.sql.gz
suffixes: ['.sql', '.gz']
Command Prompt output of Python posixpath, ntpath, PureWindowsPath and PurePosixPath getting basenames from Windows and Linux paths
posixpath returns the whole Windows path unchanged, while ntpath and PureWindowsPath return budget_2026.xlsx.

ntpath accepts forward slashes too, so it handles both styles. On Windows, the plain os.path already is ntpath. For converting strings to path objects, see converting a string to a path in Python.

Get the file name from a URL

A URL looks like a path, but query strings and percent-encoding get in the way. Parse it first:

import os
from pathlib import PurePosixPath
from urllib.parse import unquote, urlparse

url = "https://cdn.example.com/files/Q3%20Report%202026.pdf?version=4#page=2"

print("os.path.basename:", os.path.basename(url))
path = urlparse(url).path
print("from urlparse:   ", PurePosixPath(unquote(path)).name)

Output:

os.path.basename: Q3%20Report%202026.pdf?version=4#page=2
from urlparse:    Q3 Report 2026.pdf
Command Prompt output of Python getting a file name from a URL with urlparse and unquote instead of os.path.basename
basename keeps the ?version and #page parts and the %20 codes; urlparse plus unquote gives Q3 Report 2026.pdf.

PurePosixPath is right here because URLs always use forward slashes. Once you have the name, copying files to another directory is often the next step.

Get the filename of every file in a folder

With pathlib, each item from glob() already has .name and .stem, so there’s no string slicing:

from pathlib import Path

logs = Path("logs")
logs.mkdir(exist_ok=True)
for name in ["app_2026-10-04.log", "app_2026-10-05.log", "app_2026-10-06.log", "notes.txt"]:
    (logs / name).write_text("ok\n", encoding="utf-8")

for f in sorted(logs.glob("app_*.log")):
    day = f.stem.removeprefix("app_")
    print(f"{f.name:<22} -> day {day}")

Output:

app_2026-10-04.log     -> day 2026-10-04
app_2026-10-05.log     -> day 2026-10-05
app_2026-10-06.log     -> day 2026-10-06

Only the three app_*.log files match, and removeprefix() pulls out the date. To list everything in a folder, see listing files in a directory with Python.

Filename-from-path methods compared

Pathos.path.basename()Path().name
reports/q3.csv'q3.csv''q3.csv'
reports/'''reports'
Windows path on LinuxWhole stringUse PureWindowsPath
URL with ?queryIncludes the queryParse with urlparse() first

Working with file paths a lot? These are worth a read:

Frequently asked questions

How do I get the basename of a file in Python?

Use os.path.basename(path) or pathlib.Path(path).name.

What is the difference between os.path.basename and Path.name?

They match for file paths, but with a trailing slash basename returns '' and Path.name returns the folder name.

How do I get the basename without the extension?

Use Path(path).stem, for example 'sales_q3_2026'.

How do I get a basename from a Windows path on Linux?

Use ntpath.basename() or PureWindowsPath(path).name.

Can I use os.path.basename on a URL?

Not safely: it keeps the query string. Use urlparse(url).path, then unquote() and take the name.