What is the most pythonic way to join or construct paths?

Is it using the os.path.join() method, or concatenating strings? Examples:

fullpath1 = os.path.join(dir, subdir)
fullpath2 = os.path.join(dir, "subdir")
fullpath3 = os.path.join("dir", subdir)
fullpath4 = os.path.join(os.path.join(dir, subdir1), subdir2)


fullpath1 = dir + "\\" + subdir
fullpath2 = dir + "\\" + "subdir"
fullpath3 = "dir" + "\\" + subdir
fullpath4 = dir + "\\" + subdir1 + \\" + subdir2"

Edit with some more info. This is a disagreement between a colleague and I. He insists the second method is "purer", while I insist using the built in functions are actually "purer" as it would make it more pythonic, and of course it makes the path handling OS-independent.

We tried searching to see if this question had been answered before, either here in SO or elsewhere, but found nothing

In my opinion (I know, no one asked) it is indeed using Path from pathlib

import pathlib
folder = pathlib.Path('path/to/folder')
subfolder = folder / 'subfolder'

file = subfolder / 'file1.txt'

Please read into pathlib for more useful functions, one I often use is resolve and folder.exists() to check if a folder exist or subfolder.mkdir(parents=True, exist_ok=True) to create a new folder including its parents. Those are random examples, the module can do a lot more.

See https://docs.python.org/3/library/pathlib.html

You can either use the first method using os.join().
A second option is to use the Pathlib module as @DeepSpace suggested.
But the other option is way worse and harder to read so you shouldn't use it.