126

I have the following string:

a = "/home/user/Downloads/repo/test.txt"

My goal is just to create a string which contains only test, how can I do this ?

actually a comes from

f = tkFileDialog.asksaveasfile(mode='w', defaultextension=".txt")

and a is equal to a = f.name

but I realized f.name does not give me just the name of the file.

tiger
  • 225
  • 1
  • 9

3 Answers3

316

In Python 3.4+, you can use the pathlib module (included in Python's standard library):

>>> from pathlib import Path
>>> p = Path("/home/user/Downloads/repo/test.txt")
>>> print(p.stem)
test
>>> print(p.name)
test.txt
Håvard Tveite
  • 215
  • 2
  • 7
smheidrich
  • 4,063
  • 1
  • 17
  • 30
  • 16
    is there a way to get the stem and its extension? **EDIT**: looked in the documentation, the answer is `p.name` – kaki gadol Sep 25 '19 at 16:25
  • 4
    Won't work if there's multiple extensions e.g. test.original.txt. – BSalita Dec 26 '19 at 15:07
  • 5
    For the else who looking for: you can get the parent directory via: `p.parent` and suffixes (extensions) via `p.suffixes` – iedmrc Apr 26 '20 at 13:54
  • Unfortunately, `p.parent` does not yield a `Path` so it breaks the chain. :/ – Raphael Jan 03 '22 at 21:44
  • 1
    @Raphael It does. Are you using Python's native pathlib or some other package? – smheidrich Jan 04 '22 at 00:57
  • Huh. Good that you ping me; I had some code yesterday where I got `PurePosixPath` where I didn't expect it, but now I'm getting `PosixPath` and can simplify my code. Weird. Anyway, thanks for remote-rubber-ducking! :D (And yes, vanilla 3.7 `pathlib`.) – Raphael Jan 04 '22 at 14:17
17

Use the os.path module to work with paths; the os.path.basename() function gives you the last part after the last path separator, and os.path.splitext() gives you the filename with the extension split off:

import os.path

basename = os.path.splitext(os.path.basename(f.name))[0]

Using the os.path functions ensures that your code will continue to work correctly on different operating systems, even if the path separators are different.

In Python 3.4 or newer (or as a separate backport install), you can also use the pathlib library, which offers a more object-oriented approach to path handling. pathlib.Path() objects have a .stem attribute, which is the final component without the extension suffix:

try:
    import pathlib
except ImportError:
    # older Python version, import the backport instead
    import pathlib2 as pathlib

basename = pathlib.Path(f.name).stem

Demo:

>>> import os.path
>>> a = "/home/user/Downloads/repo/test.txt"
>>> os.path.basename(a)
'test.txt'
>>> os.path.splitext(os.path.basename(a))
('test', '.txt')
>>> os.path.splitext(os.path.basename(a))[0]
'test'
>>> import pathlib
>>> pathlib.Path(a)
PosixPath('/home/user/Downloads/repo/test.txt')
>>> pathlib.Path(a).stem
'test'
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
2

It seems that you're either looking for os.path.basename or os.path.splitext:

>>> import os.path
>>> os.path.basename("/var/log/err.log")
'err.log'
>>> os.path.splitext(os.path.basename("/var/log/err.log"))
('err', '.log')
>>> os.path.splitext(os.path.basename("/var/log/err.log"))[0]
'err'
>>>
mroman
  • 1,354
  • 9
  • 14