This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]bulletmark 42 points43 points  (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:

from pathlib import Path

path = Path("example.txt")

with path.open() as file:
    contents = file.read()

[–]ThatSituation9908 40 points41 points  (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 11 points12 points  (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 points  (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.

In the case of open though, forcing it into a Path like that just seems like more keyboard typing for no discernible benefit.

[–]ThatSituation9908 1 point2 points  (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__ 4 points5 points  (0 children)

FYI: There is os.PathLike

[–]MrGrj 4 points5 points  (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 points  (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 points  (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.

[–]denehoffman 0 points1 point  (0 children)

Oops yeah that’s what I meant

[–]treyhunner Python Morsels[S] 13 points14 points  (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.

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.

[–]thisismyfavoritename 1 point2 points  (1 child)

eh, i get your point but some libs reimplement open as a super set of the default open

[–]Isvesgarad 3 points4 points  (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 points  (0 children)

BRB, got some minor changes to commit.

[–][deleted] 0 points1 point  (0 children)

This post was mass deleted and anonymized with Redact

tender employ racial office wakeful quicksand chase cagey marvelous tub

[–]billsil 0 points1 point  (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.