124

In python I have variables base_dir and filename. I would like to concatenate them to obtain fullpath. But under windows I should use \ and for POSIX / .

fullpath = "%s/%s" % ( base_dir, filename ) # for Linux

How can I make this platform independent?

John Smith
  • 7,243
  • 6
  • 49
  • 61
Jakub M.
  • 32,471
  • 48
  • 110
  • 179
  • 1
    possible duplicate of [Platform-independent file paths?](http://stackoverflow.com/questions/6036129/platform-independent-file-paths) – Felix Kling Jun 06 '12 at 16:59
  • 1
    Possible duplicate of [Platform-independent file paths?](https://stackoverflow.com/questions/6036129/platform-independent-file-paths) – jww Aug 24 '19 at 05:55
  • See also [this answer on Why use os.path.join over string concatenation?](https://stackoverflow.com/a/13944874/1078556) – danicotra May 16 '20 at 09:27

6 Answers6

202

You want to use os.path.join() for this.

The strength of using this rather than string concatenation etc is that it is aware of the various OS specific issues, such as path separators. Examples:

import os

Under Windows 7:

base_dir = r'c:\bla\bing'
filename = r'data.txt'

os.path.join(base_dir, filename)
'c:\\bla\\bing\\data.txt'

Under Linux:

base_dir = '/bla/bing'
filename = 'data.txt'

os.path.join(base_dir, filename)
'/bla/bing/data.txt'

The os module contains many useful methods for directory, path manipulation and finding out OS specific information, such as the separator used in paths via os.sep

Levon
  • 138,105
  • 33
  • 200
  • 191
27

Use os.path.join():

import os
fullpath = os.path.join(base_dir, filename)

The os.path module contains all of the methods you should need for platform independent path manipulation, but in case you need to know what the path separator is on the current platform you can use os.sep.

Andrew Clark
  • 202,379
  • 35
  • 273
  • 306
25

Digging up an old question here, but on Python 3.4+ you can use pathlib operators:

from pathlib import Path

# evaluates to ./src/cool-code/coolest-code.py on Mac
concatenated_path = Path("./src") / "cool-code\\coolest-code.py"

It's potentially more readable than os.path.join() if you are fortunate enough to be running a recent version of Python. But, you also tradeoff compatibility with older versions of Python if you have to run your code in, say, a rigid or legacy environment.

70by7
  • 586
  • 5
  • 8
  • I am very fond of `pathlib`. However, it is often not installed by default in Python2 installations. If you do not want users to have to go through installing pathlib as well, `os.path.join()` is the simpler way to go. – Marcel Waldvogel Jun 16 '19 at 12:58
  • The `/` operator is convenient when working with existing objects. When using the constructor directly, you can just pass multiple arguments to construct the path. i.e. `Path("./src", "cool-code", "coolest-code.py")` – Tomerikoo Jun 29 '22 at 08:14
11
import os
path = os.path.join("foo", "bar")
path = os.path.join("foo", "bar", "alice", "bob") # More than 2 params allowed.
varunl
  • 19,499
  • 5
  • 29
  • 47
0

I've made a helper class for this:

import os

class u(str):
    """
        Class to deal with urls concat.
    """
    def __init__(self, url):
        self.url = str(url)

    def __add__(self, other):
        if isinstance(other, u):
            return u(os.path.join(self.url, other.url))
        else:
            return u(os.path.join(self.url, other))

    def __unicode__(self):
        return self.url

    def __repr__(self):
        return self.url

The usage is:

    a = u("http://some/path")
    b = a + "and/some/another/path" # http://some/path/and/some/another/path
sashab
  • 1,534
  • 2
  • 19
  • 36
0

Thanks for this. For anyone else who sees this using fbs or pyinstaller and frozen apps.

I can use the below which works perfect now.

target_db = os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), "sqlite_example.db")

I was doing this fugliness before which was obviously not ideal.

if platform == 'Windows':
    target_db = (os.path.abspath(os.path.dirname(sys.argv[0])) + "\\" + "sqlite_example.db")

if platform == 'Linux' or 'MAC':
    target_db = (os.path.abspath(os.path.dirname(sys.argv[0])) + "/" + "sqlite_example.db")

target_db_path = target_db
print(target_db_path)
Mike R
  • 679
  • 7
  • 13