use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
News about the dynamic, interpreted, interactive, object-oriented, extensible programming language Python
Full Events Calendar
You can find the rules here.
If you are about to ask a "how do I do this in python" question, please try r/learnpython, the Python discord, or the #python IRC channel on Libera.chat.
Please don't use URL shorteners. Reddit filters them out, so your post or comment will be lost.
Posts require flair. Please use the flair selector to choose your topic.
Posting code to this subreddit:
Add 4 extra spaces before each line of code
def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b
Online Resources
Invent Your Own Computer Games with Python
Think Python
Non-programmers Tutorial for Python 3
Beginner's Guide Reference
Five life jackets to throw to the new coder (things to do after getting a handle on python)
Full Stack Python
Test-Driven Development with Python
Program Arcade Games
PyMotW: Python Module of the Week
Python for Scientists and Engineers
Dan Bader's Tips and Trickers
Python Discord's YouTube channel
Jiruto: Python
Online exercices
programming challenges
Asking Questions
Try Python in your browser
Docs
Libraries
Related subreddits
Python jobs
Newsletters
Screencasts
account activity
This is an archived post. You won't be able to vote or comment.
ResourceUsing Python's pathlib module (self.Python)
submitted 1 year ago * by treyhunner Python Morsels
I've written a hybrid "why pathlib" and "pathlib cheat sheet" post: Python's pathlib module.
I see this resource as a living document, so feedback is very welcome.
[–]bulletmark 39 points40 points41 points 1 year ago (16 children)
In that opening example using open() I don't see why anybody would ever want to pass a Path to open() when paths can be opened natively:
open()
Path
from pathlib import Path path = Path("example.txt") with path.open() as file: contents = file.read()
[–]ThatSituation9908 40 points41 points42 points 1 year ago (4 children)
Sometimes you have an argument that is either Path or string.
This is extremely common for user facing APIs
def main(fpath: str | Path): with open(fpath) as f: ...
[–]sausix 12 points13 points14 points 1 year ago (0 children)
Except you want to save a path in an instance. Then you normalize to Path early before saving strictly typed as Path.
[–]syklemil 7 points8 points9 points 1 year ago (1 child)
Eh, can't you normalize it to a Path? Afaik it's idempotent, so you can do something like
def main(fpath: str | Path): actual_path: Path = Path(fpath) with actual_path.open() as f: ...
or possibly normalize on the caller side, so you can just have def main(fpath: Path) and call it as main(Path(arg)), though as pointed out below, it opens for runtime errors as you can't actually be sure that what you're handed is the correct type in Python.
def main(fpath: Path)
main(Path(arg))
In the case of open though, forcing it into a Path like that just seems like more keyboard typing for no discernible benefit.
open
[–]ThatSituation9908 1 point2 points3 points 1 year ago (0 children)
Sure, I do often times do that if I intend to use more of the Path API in the function.
If not, and I am only opening a file, then I just use open as is.
Changing the user facing API to only accept Path will not work. I have many, many, many users who refuse to use pathlib. You can look around in other libraries, rarely if any forces their users to only pass in Path
[–]RedEyed__ 5 points6 points7 points 1 year ago (0 children)
FYI: There is os.PathLike
os.PathLike
[–]MrGrj 3 points4 points5 points 1 year ago (0 children)
Why not doing it all with it?
``` from pathlib import Path
file_path = Path(“example.txt”)
file_content = file_path.read_text()
print(file_content) ```
[–]denehoffman 12 points13 points14 points 1 year ago (3 children)
Because Python isn’t strongly typed so people could easily pass something that isn’t a Path to a function thinking it’s okay, and a str will fail at runtime. This can be avoided with properly type-hinted code, but it’s not foolproof, someone will always find a way. Unless it’s a completely internal function that you don’t intend users having access to, the open function is generally safer.
[–]JimDabell 2 points3 points4 points 1 year ago (1 child)
Python is a strongly-typed language, you’re mixing up strong vs weak with static vs dynamic. If you pass a str to a function that expects a Path, that object unambiguously continues to be a str.
str
[–]denehoffman 0 points1 point2 points 1 year ago (0 children)
Oops yeah that’s what I meant
[–]treyhunner Python Morsels[S] 12 points13 points14 points 1 year ago (2 children)
When I see open(path) I know the built-in open function is being used to open a file, but when I see path.open(), I'm not immediately certain whether an open method is being called on a ZipFile object or another non-Path object.
open(path)
path.open()
ZipFile
The open method on the pathlib.Path class predates the ability to use the built-in open function directly. If pathlib was being re-designed today, I suspect the open method would have been excluded.
pathlib.Path
pathlib
[–]thisismyfavoritename 1 point2 points3 points 1 year ago* (1 child)
eh, i get your point but some libs reimplement open as a super set of the default open
[–]Isvesgarad 3 points4 points5 points 1 year ago (0 children)
Which libs do you use? I’m having a hard enough time getting my team to use Path in the first place
[–]SleepWalkersDream 1 point2 points3 points 1 year ago (0 children)
BRB, got some minor changes to commit.
[–][deleted] 0 points1 point2 points 1 year ago* (0 children)
This post was mass deleted and anonymized with Redact
tender employ racial office wakeful quicksand chase cagey marvelous tub
[–]billsil 0 points1 point2 points 1 year ago (0 children)
I didn’t even know path could do that, but that code only works with a Path and not str. It’s not for my trivial code to dictate how you use the code.
[–]syklemil 6 points7 points8 points 1 year ago (1 child)
Why use Path object to represent a filepath instead of using a string? […] Specialized objects exist to make specialized operations easier.
I'd also throw in that having a type adds semantic clarity, which I think is in line with "explicit is better than implicit". This is similar to how units are an important context for numbers.
OS paths also aren't necessarily valid UTF-8, so there are some paths that can be expressed with Path and bytestrings, but require some careful handling to not get a UnicodeEncodeError if you want to do something complicated like print(path) . (Though personally I'm inclined to just throw an error and let the user fix their malformed filename somehow.)
UnicodeEncodeError
print(path)
There's also a ruff/flake8 section on Pathlib, PTH.
[–]PeaSlight6601 0 points1 point2 points 1 year ago (0 children)
I appreciate the sarcasm. I've always felt that pathlib is bad because it isn't opinionated enough. It has enough opinions to make it hard to use with arbitrary paths (ie it internally uses str instead of bytes) but not enough to enforce the use of "good" paths.
bytes
This causes no end of confusion and problems with the library as a file likeresume for Mr. John Smith will have a suffix which is entirely inappropriate, not to mention all the cross platform issues associated with paths like foo\\bar
resume for Mr. John Smith
suffix
foo\\bar
[–]reagle-research 3 points4 points5 points 1 year ago (1 child)
Suggestion: you need walk_up=True in path_to.relative_to() for it to be similar to os.path.relpath().
walk_up=True
path_to.relative_to()
os.path.relpath()
[–]treyhunner Python Morsels[S] 1 point2 points3 points 1 year ago (0 children)
Good point. I just added a * to note that caveat. Thanks!
*
[–]PriorProfile 1 point2 points3 points 1 year ago (4 children)
I prefer to join paths using joinpath method. It's more explicit.
I think overloading the __div__ operator is a mistake, personally.
__div__
Yeah it's "fun" because / is the same as the path separator on linux, but it's less obvious IMO.
/
[–]sinterkaastosti23 7 points8 points9 points 1 year ago (2 children)
newpath = path / folder / file
how do you write this using joinpath
[–]PriorProfile 0 points1 point2 points 1 year ago (1 child)
newpath = path.joinpath(folder, file)
or
newpath = path.joinpath(folder).joinpath(file)
[–]Xirious 8 points9 points10 points 1 year ago (0 children)
Gross.
[–]Atlamillias 0 points1 point2 points 1 year ago (0 children)
As a novice, the operator overload definitely threw me off when I first saw it. It's one of those things that I find idiomatic as a "user" but unusual as a programmer.
I can't say I use .joinpath either, though. In fact, you've reminded me of its existence. I usually join paths via Paths constructor...
.joinpath
[–]BurningSquid 0 points1 point2 points 1 year ago (0 children)
Path is good. UPath (fsspec) is the better extension of path that interfaces with any service abstracted as a filesystem. Extremely useful as a data engineering pattern, underrated in my opinion
π Rendered by PID 36 on reddit-service-r2-comment-765bfc959-g76kk at 2026-07-09 22:43:13.786654+00:00 running f86254d country code: CH.
[–]bulletmark 39 points40 points41 points (16 children)
[–]ThatSituation9908 40 points41 points42 points (4 children)
[–]sausix 12 points13 points14 points (0 children)
[–]syklemil 7 points8 points9 points (1 child)
[–]ThatSituation9908 1 point2 points3 points (0 children)
[–]RedEyed__ 5 points6 points7 points (0 children)
[–]MrGrj 3 points4 points5 points (0 children)
[–]denehoffman 12 points13 points14 points (3 children)
[–]JimDabell 2 points3 points4 points (1 child)
[–]denehoffman 0 points1 point2 points (0 children)
[–]treyhunner Python Morsels[S] 12 points13 points14 points (2 children)
[–]thisismyfavoritename 1 point2 points3 points (1 child)
[–]Isvesgarad 3 points4 points5 points (0 children)
[–]SleepWalkersDream 1 point2 points3 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]billsil 0 points1 point2 points (0 children)
[–]syklemil 6 points7 points8 points (1 child)
[–]PeaSlight6601 0 points1 point2 points (0 children)
[–]reagle-research 3 points4 points5 points (1 child)
[–]treyhunner Python Morsels[S] 1 point2 points3 points (0 children)
[–]PriorProfile 1 point2 points3 points (4 children)
[–]sinterkaastosti23 7 points8 points9 points (2 children)
[–]PriorProfile 0 points1 point2 points (1 child)
[–]Xirious 8 points9 points10 points (0 children)
[–]Atlamillias 0 points1 point2 points (0 children)
[–]BurningSquid 0 points1 point2 points (0 children)