Незалежне конкатенація шляху від платформи за допомогою “/”, “\”?


83

У python у мене є змінні base_dirта filename. Я хотів би об’єднати їх для отримання fullpath. Але під вікнами я повинен використовувати\ і для POSIX/ .

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

Як я можу зробити цю платформу незалежною?



Можливий дублікат шляхів до файлів, незалежних
jww

Відповіді:


145

Ви хочете використовувати для цього os.path.join () .

Сила використання цього, а не конкатенації рядків тощо полягає в тому, що він обізнаний про різні специфічні для ОС проблеми, такі як роздільники шляхів. Приклади:

import os

Під Windows 7 :

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

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

Під Linux :

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

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

Модуль os містить багато корисних методів для каталогів, маніпуляцій із шляхами та пошуку конкретної інформації для ОС, таких як роздільник, який використовується в шляхах через os.sep


26

Використання os.path.join():

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

Модуль os.path містить усі методи, необхідні для маніпулювання незалежними від платформи шляхами, але у випадку, якщо вам потрібно знати, що таке роздільник шляхів на поточній платформі, яку ви можете використовувати os.sep.


1
це не повний шлях, якщо base_dirце відносний шлях (незважаючи на те, що OP використовує його)
jfs

1
Додавання abspath()дзвінка має зробити його повним шляхом, якщо в ньому є щось відносне.
martineau

@Andrew Clark, os.sep повертає "\\" у Windows, але це все одно працює, навіть якщо я використовую "/". Чи є якісь проблеми, якщо ми просто використовуємо "/"?
multigoodverse

12

Викопуємо тут старе запитання, але на Python 3.4+ ви можете використовувати оператори pathlib :

from pathlib import Path

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

Це потенційно читабельніше, ніж os.path.join()якщо вам пощастить запустити останню версію Python. Але ви також обмежуєте сумісність зі старими версіями Python, якщо вам доводиться запускати свій код у, скажімо, жорсткому або застарілому середовищі.


Я дуже люблю pathlib. Однак він часто не встановлюється за замовчуванням у установках Python2. Якщо ви не хочете, щоб користувачам також потрібно було пройти встановлення pathlib, os.path.join()це простіший спосіб.
Марсель Вальдвогель,

7
import os
path = os.path.join("foo", "bar")
path = os.path.join("foo", "bar", "alice", "bob") # More than 2 params allowed.

1

Я зробив для цього допоміжний клас:

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

Використання:

    a = u("http://some/path")
    b = a + "and/some/another/path" # http://some/path/and/some/another/path

Чи не буде це вставляти зворотні скісні риски в Windows?
Марсель Вальдвогель,

0

Дякую за це. Для всіх, хто бачить це за допомогою fbs або pyinstaller та заморожених додатків.

Я можу скористатися наведеним нижче, що зараз ідеально працює.

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

Я робив цю хитрість, яка раніше, очевидно, не була ідеальною.

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.