79

They are same, but which one should I use?

http://docs.python.org/library/os.html:

os.sep

The character used by the operating system to separate pathname components. This is '/' for POSIX and '\' for Windows. Note that knowing this is not sufficient to be able to parse or concatenate pathnames — use os.path.split() and os.path.join() — but it is occasionally useful. Also available via os.path.

Community
  • 1
  • 1
zhigang
  • 6,597
  • 4
  • 30
  • 24
  • 2
    They are NOT always the same. For instance, on Mac OS X, `os.sep` returns `/`, but `os.pathsep` returns `:`. – jvriesem Dec 13 '16 at 17:09
  • 3
    @jvriesem `os.pathsep` is supposed to be different than `os.path.sep` and `os.sep`. See [os.pathsep](https://docs.python.org/2/library/os.html#os.pathsep) vs [os.sep](https://docs.python.org/2/library/os.html#os.sep) –  Dec 30 '16 at 19:19
  • 12
    Just to make this clear to readers who, like me, may have misread the comments by jvriesem and JETM. `os.sep` and `os.path.sep` are consistent in their values on any OS, `os.pathsep` (no dot between path and sep) is something [completely different](https://docs.python.org/2/library/os.html#os.pathsep). – mattst Apr 02 '17 at 20:21

6 Answers6

96

I'd use os.path.sep to make it very clear that it's the path separator… But consistency is more important, so if one is already being used, use that. Otherwise, pick one and use it all the time.

Edit: Just to make sure you're not reinventing the wheel, though, the path module already has join, split, dirname, and basename functions… So you should rarely need to use path.sep:

>>> os.path.join("foo", "bar", "baz")
'foo/bar/baz'
>>> os.path.split(_)
('foo/bar', 'baz')
David Wolever
  • 148,955
  • 89
  • 346
  • 502
  • 2
    It seems the doc only documents os.sep, and it seems there are more places using os.sep than os.path.sep. I agree with you that os.path.sep is more clear. Is there any consideration from the original designer's point of view that we don't know? – zhigang Aug 01 '11 at 15:38
  • 1
    That's odd, because `sep` is actually defined in the `path` module (well, specifically, the `${SYSTEM}path` module, where `$SYSTEM` is, eg, `posix`, `nt`, etc), and explicitly imported into `os` (from `os.py`, after the correct os-specfic “os” and “path” modules have been loaded: `from os.path import (…, sep, …)`. – David Wolever Aug 01 '11 at 15:43
  • 1
    So, tl;dr: I'm not sure. It would make sense if *all* of the `path` module was imported into `os`… But some parts (ex, `path.join`) aren't. – David Wolever Aug 01 '11 at 15:44
  • 1
    zhigang: The documentation you quoted in the question says "Also available via os.path." – Sven Marnach Aug 01 '11 at 16:32
  • Yeah. I see. Does that mean 'os.sep' is preferred? – zhigang Aug 01 '11 at 22:46
  • I don't know, and I don't think it matters all that much. I'd prefer `os.path.sep`. The standard library seems to prefer `os.sep` (grepping for it has 65 hits verses 11 hits for `path.sep`). Honestly, if I was reading a code base, the only thing that would annoy me is if the two were used inconsistently. – David Wolever Aug 01 '11 at 23:39
  • as of python 2.7.3. do: `os.path.join(*['foo', 'bar', 'baz'])` – Alexander Oh Feb 12 '13 at 07:36
  • D'oh! Thanks @Alex, that is correct. I've updated my answer accordingly. – David Wolever Feb 12 '13 at 08:59
  • How do you get ['foo', 'bar', 'baz'] with python 2.7.1 and ever since 1995 I've been getting:
    >>> os.path.join("foo", "bar", "baz")
    'foo/bar/baz'
    >>> os.path.split(_)
    ('foo/bar', 'baz')
    – thanos Jul 15 '13 at 00:46
  • I… have no idea what was going through my head when I wrote that. Fixed now. Thanks! – David Wolever Jul 15 '13 at 04:02
  • +1 for mentioning that the explicit use of `path.sep` is rarely necessary. – halloleo Oct 15 '14 at 08:50
  • @DavidWolever I find it odd that `os.path.sep` is not mentioned in the [documentation for os.path](https://docs.python.org/2.7/library/os.path.html), nor in the [3.6-dev docs](https://docs.python.org/3.6/library/os.path.html). But [`os.sep`](https://docs.python.org/2.7/library/os.html#os.sep) is. However, [`os.path.supports_unicode_filenames`](https://docs.python.org/2/library/os.path.html#os.path.supports_unicode_filenames) (a constant/read-only/property) is mentioned. Perhaps a bug to be filed. – aneroid Sep 02 '15 at 07:58
15

I recommend you use os.path.sep for clarity, since it's a path separator, not an OS separator. If you import os.path as path you can call it path.sep, which is even better.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 1
    I find it odd that `os.path.sep` is not mentioned in the [documentation for os.path](https://docs.python.org/2.7/library/os.path.html), nor in the [3.6-dev docs](https://docs.python.org/3.6/library/os.path.html). But [`os.sep`](https://docs.python.org/2.7/library/os.html#os.sep) is. However, [`os.path.supports_unicode_filenames`](https://docs.python.org/2/library/os.path.html#os.path.supports_unicode_filenames) (a constant/read-only/property) is mentioned. Perhaps a bug to be filed. – aneroid Sep 02 '15 at 07:53
  • I'd guess they leave it undocumented intentionally to encourage the use of `os.sep`. Could be wrong though. – Betamos Jun 19 '17 at 16:59
9

If you are using Python 2.7, I suggest using os.sep (works) instead of os.path.sep (broken) as Jython on Windows has a bug returning a "/" slash instead of the required "\" backslash.

mpx
  • 3,081
  • 2
  • 26
  • 56
scottwed
  • 187
  • 2
  • 12
2

The following examples could highlight the differences between os.path.join and os.path.sep.join.

>>> import os
>>> os.path.join("output", "images", "saved")
'output/images/saved'
>>> os.path.sep.join(["output", "images", "saved"])
'output/images/saved'

I guess the os.path.sep.join is more robust and can be used w/o modifications for any os.

alexwlchan
  • 5,699
  • 7
  • 38
  • 49
passion
  • 387
  • 4
  • 16
  • It almost seems like this is the actual purpose of the `os.path.sep` class. – Chris Wong Oct 30 '21 at 00:06
  • I don't see any difference in the output, neither a reason why the secondo way should be more robust. As far as I know, also the first one is cross-system. In my opinion is always better to use the first, as it is a function which joins path, while the second join strings, but I believe it is just a conceptual difference. I would use path sep only when needed for string operations (e.g. to pass as argument to a function which wants a folder with final separator). – Vincenzooo Aug 08 '22 at 21:29
1
  1. As mentioned in the python docs, both os.path.sep and os.sep return the same output.

The character used by the operating system to separate pathname components. This is '/' for POSIX and '\' for Windows.

  1. Both of them belongs to the same python class also.

    print(type(os.sep))
    print(type(os.path.sep))
    
    # Output
    <class 'str'>
    <class 'str'>
    
  2. Both have them have the same documentation.

    print(os.path.sep.__doc__)
    print(os.sep.__doc__)
    
    # The outputs of both print statements are the same. 
    

So, I think after Python2 where we mostly used os.sep, in Python3 only the consistency matters as far as their uses are concerned.

rs_punia
  • 421
  • 2
  • 6
  • 17
0

I have had os.path.sep return ':' in linux on python 2.7 which should be the result of os.pathsep (no second dot) but have never had the same issue with os.sep. Never did find out why but os.sep always solved the problem.

Preston
  • 1,300
  • 1
  • 17
  • 32