19

I have a directory I'd like to print out with a trailing slash: my_path = pathlib.Path('abc/def')

Is there a nicer way of doing this than os.path.join(str(my_path), '')?

Tom
  • 42,844
  • 35
  • 95
  • 101

3 Answers3

36

No, you didn't miss anything. By design, pathlib strips trailing slashes, and provides no way to display paths with trailing slashes. This has annoyed several people, as mentioned in the bug tracker: pathlib strips trailing slash.

A compact way to add slashes in Python 3.6 is to use an f-string, eg f'{some_path}/' or f'{some_path}{os.sep}' if you want to be OS-agnostic.

from pathlib import Path
import os

some_path = '/etc'
p = Path(some_path)
print(f'{p}/')
print(f'{p}{os.sep}')

output

/etc/
/etc/

Another option is to add a dummy component and slice it off the resulting string:

print(str(p/'@')[:-1])
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
  • The two ways may not equivalent: `os.sep` always represents the separator of the system’s path flavour, while a path can have a different separator. – Eugene Yarmash Nov 30 '17 at 13:12
  • @EugeneYarmash Indeed. But the OP is simply adding a slash for display purposes: "I have a directory I'd like to print out with a trailing slash". So we don't really need to worry about it for this particular case. And if you're actually building paths with `pathlib`, then you should let `pathlib` handle the details... unless you're in the situation mentioned in that bug tracker link and you need to supply a pathname with a trailing slash to some program that needs it, and in which case you're probably on a Posix system anyway. – PM 2Ring Nov 30 '17 at 13:28
  • The dummy component is probably preferable - there are paths without trailing slashes where `p/` doesn't add `os.sep`, e.g. `Path(/)` etc (`/` can be a valid parent for example, e.g. `Path(/rootfile.txt)`, so using `os.sep` to connect `path.parent` and `path.name` in general would be wrong!) – GPhys Sep 22 '21 at 03:57
  • @GPhys Sure, but this question (& my answer) is about manipulating path *strings* to make a human-friendly representation for printing (but I guess it's also useful for saving path strings to CSV, JSON, etc). The main motivation for the `pathlib` module is to treat paths as objects and to manipulate them using the module functions / methods, so as to avoid the problems that can arise with the old `os.path` string-oriented approach. – PM 2Ring Sep 22 '21 at 04:40
  • The question is explicitly about pathlib directories; `Path("/")` is a pathlib directory (`is_dir()` is `True`) – GPhys Sep 22 '21 at 07:19
3

To add a trailing slash of the path's flavour using just pathlib you could do:

>>> from pathlib import Path
>>> my_path = Path("abc/def")
>>> str(my_path / "_")[:-1]  # add a dummy "_" component, then strip it
'abc/def/'

Looking into the source, there's also a Path._flavour.sep attribute:

>>> str(my_path) + my_path._flavour.sep
'abc/def/'

But it doesn't seem to have any documented accessor yet.

Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
  • Thanks for that info about `_flavour.sep`, although I'm wary about using undocumented features: they can disappear without notice. ;) – PM 2Ring Nov 30 '17 at 11:38
1

You could also use:

os.path.normpath(str(my_path)) + os.sep

I would say it is down to preference rather than being "nicer"

Niels
  • 174
  • 5
  • to clarify, i'm hoping there's something i missed in the `Path` class itself... seems a cop-out to import `os.path` to do the job. – Tom Nov 30 '17 at 11:31
  • and `os.path.normpath(my_path)` raises "AttributeError: 'PosixPath' object has no attribute 'startswith'" --> needs to be `os.path.normpath(str(my_path))` – Tom Nov 30 '17 at 11:32
  • 2
    @Tom, no you didn't miss anything. By design, `pathlib` strips trailing slashes, and provides no way to display paths with trailing slashes. This has annoyed several people, see [here](https://bugs.python.org/issue21039). A compact way to add slashes in Python 3.6 is to use an f-string, eg `f'{some_path}/'` or `f'{some_path}{os.sep}'` if you want to be OS-agnostic. – PM 2Ring Nov 30 '17 at 11:37
  • I think that deserves to be an answer as it's the neatest option by far (though i'm stuck on 3.4 for a while :( ) – Tom Nov 30 '17 at 11:38
  • 3
    @Tom Oh, ok. I don't normally do f-string answers, since they can be frustrating for people using older versions. Beware: f-strings are _highly_ addictive, and _much_ faster than the other formatting options. :) – PM 2Ring Nov 30 '17 at 11:41
  • 1
    3.6 is nearly a year old, people should be shown the reasons to upgrade :) – Tom Nov 30 '17 at 11:46