Относительные пути в Python - программирование

Относительные пути в Python

Я создаю простой помощник script для работы, который скопирует пару файлов шаблонов в нашей базе кода в текущий каталог. Однако у меня нет абсолютного пути к каталогу, в котором хранятся шаблоны. У меня есть относительный путь от script, но когда я вызываю script, он рассматривает это как путь относительно текущего рабочего каталога. Есть ли способ указать, что этот относительный URL-адрес находится из местоположения script?

4b9b3361

Ответ 1

В файле, который имеет скрипт, вы хотите сделать что-то вроде этого:

import os
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'relative/path/to/file/you/want')

Это даст вам абсолютный путь к файлу, который вы ищете. Обратите внимание: если вы используете setuptools, скорее всего, вы должны использовать его API ресурсов пакетов.

UPDATE: я отвечаю на комментарий здесь, поэтому могу вставить образец кода. :-)

Правильно ли я __file__ что __file__ не всегда доступен (например, когда вы запускаете файл напрямую, а не импортируете его)?

Я предполагаю, что вы имеете в виду скрипт __main__ когда вы упоминаете, как запустить файл напрямую. Если это так, это не похоже на мою систему (python 2.5.1 на OS X 10.5.7):

#foo.py
import os
print os.getcwd()
print __file__

#in the interactive interpreter
>>> import foo
/Users/jason
foo.py

#and finally, at the shell:
~ % python foo.py
/Users/jason
foo.py

Тем не менее, я знаю, что есть некоторые причуды с __file__ на C-расширениях. Например, я могу сделать это на своем Mac:

>>> import collections #note that collections is a C extension in Python 2.5
>>> collections.__file__
'/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-
dynload/collections.so'

Однако это вызывает исключение на моей машине Windows.

Ответ 2

вам нужно os.path.realpath (образец ниже добавляет родительский каталог к ​​вашему пути)

import sys,os
sys.path.append(os.path.realpath('..'))

Ответ 3

Как указано в принятом ответе

import os
dir = os.path.dirname(__file__)
filename = os.path.join(dir, '/relative/path/to/file/you/want')

Я просто хочу добавить, что

последняя строка не может начинаться с обратного слэша, не вводить строку должен включать обратную косую черту

Это должно быть что-то вроде

import os
dir = os.path.dirname(__file__)
filename = os.path.join(dir, 'relative','path','to','file','you','want')

В некоторых случаях принятый ответ может вводить в заблуждение, обратитесь к this для получения более подробной информации

Ответ 4

Рассмотрим мой код:

import os


def readFile(filename):
    filehandle = open(filename)
    print filehandle.read()
    filehandle.close()



fileDir = os.path.dirname(os.path.realpath('__file__'))
print fileDir

#For accessing the file in the same folder
filename = "same.txt"
readFile(filename)

#For accessing the file in a folder contained in the current folder
filename = os.path.join(fileDir, 'Folder1.1/same.txt')
readFile(filename)

#For accessing the file in the parent folder of the current folder
filename = os.path.join(fileDir, '../same.txt')
readFile(filename)

#For accessing the file inside a sibling folder.
filename = os.path.join(fileDir, '../Folder2/same.txt')
filename = os.path.abspath(os.path.realpath(filename))
print filename
readFile(filename)

Ответ 5

См. sys.path Как инициализировано при запуске программы, первым элементом этого списка является путь [0], это каталог, содержащий script, который использовался для вызова интерпретатора Python.

Используйте этот путь как корневую папку, из которой вы примените свой относительный путь

>>> import sys
>>> import os.path
>>> sys.path[0]
'C:\\Python25\\Lib\\idlelib'
>>> os.path.relpath(sys.path[0], "path_to_libs") # if you have python 2.6
>>> os.path.join(sys.path[0], "path_to_libs")
'C:\\Python25\\Lib\\idlelib\\path_to_libs'

Ответ 6

Вместо того, чтобы использовать

import os
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'relative/path/to/file/you/want')

как и в принятом ответе, было бы более надежно использовать:

import inspect
import os
dirname = os.path.dirname(os.path.abspath(inspect.stack()[0][1]))
filename = os.path.join(dirname, 'relative/path/to/file/you/want')

потому что использование __file__ вернет файл, из которого был загружен модуль, если он был загружен из файла, поэтому, если файл со сценарием вызывается из другого места, возвращаемый каталог будет неправильным.

Эти ответы дают более подробную информацию: fooobar.com/questions/6891/... и fooobar.com/questions/6891/...

Ответ 7

Этот код вернет абсолютный путь к основному script.

import os
def whereAmI():
    return os.path.dirname(os.path.realpath(__import__("__main__").__file__))

Это будет работать даже в модуле.

Ответ 8

Это 2018 сейчас, и Python уже давно эволюционировали до __future__. Итак, как насчет использования удивительного pathlib входящего в Python 3.4 для выполнения задачи, а не для борьбы с os, os.path, glob, shutil и т.д.

Итак, у нас есть 3 пути (возможно, дублируется):

  • mod_path: это путь простого вспомогательного скрипта
  • src_path: содержит пару файлов шаблонов, ожидающих копирования.
  • cwd: текущий каталог, назначение этих файлов шаблонов.

и проблема в том, что у нас нет полного пути к src_path, но знаю только относительный путь к mod_path.

Теперь разрешите это с удивительным pathlib:

# Hope you don't be imprisoned by legacy Python code :)
from pathlib import Path

# 'cwd': current directory is straightforward
cwd = Path.cwd()

# 'mod_path': According to the accepted answer and combine with future power
# if we are in the 'helper_script.py'
mod_path = Path(__file__).parent
# OR if we are 'import helper_script'
mod_path = Path(helper_script.__file__).parent

# 'src_path': with the future power, it just so straightforward
relative_path_1 = 'same/parent/with/helper/script/'
relative_path_2 = '../../or/any/level/up/'
src_path_1 = (mod_path / relative_path_1).resolve()
src_path_2 = (mod_path / relative_path_2).resolve()

В будущем это просто так просто. : D


Кроме того, мы можем выбирать и проверять и копировать/перемещать эти файлы шаблонов с помощью pathlib:

if src_path != cwd:
    # When we have different types of files in the 'src_path'
    for template_path in src_path.glob('*.ini'):
        fname = template_path.name
        target = cwd / fname
        if not target.exists():
            # This is the COPY action
            with target.open(mode='wb') as fd:
                fd.write(template_path.read_bytes())
            # If we want MOVE action, we could use:
            # template_path.replace(target)

Ответ 9

Привет, прежде всего, вы должны понимать функции os.path.abspath(путь) и os.path.relpath(путь)

Короче os.path.abspath(путь) делает относительный путь до абсолютного пути. И если предоставленный путь сам по себе является абсолютным путем, то функция возвращает тот же путь.

аналогично os.path.relpath(путь) делает абсолютный путь относительным путем. И если предоставленный путь сам по себе является относительным путем, то функция возвращает тот же путь.

Ниже приведен пример, позволяющий правильно понимать приведенную выше концепцию:

Предположим, у меня есть файл input_file_list.txt, который содержит список входных файлов, которые будут обрабатываться моим python script.

D:\конц\input1.dic

D:\конц\input2.dic

D:\Copyioconc\input_file_list.txt

Если вы видите выше структуру папок, input_file_list.txt присутствует в папке Copyofconc, а файлы, которые будут обрабатываться с помощью python script, присутствуют в Конк

Но содержимое файла input_file_list.txt выглядит следующим образом:

..\конц\input1.dic

..\конц\input2.dic

И мой python script присутствует в драйвере D:.

И относительный путь, указанный в файле input_file_list.txt, относится к пути к файлу input_file_list.txt.

Итак, когда python script должен выполнить текущий рабочий каталог (используйте os.getcwd(), чтобы получить путь)

Поскольку мой относительный путь относится к input_file_list.txt, то есть "D:\Copyofconc" , мне нужно изменить текущий рабочий каталог на D:\Copyofconc ".

Поэтому мне нужно использовать os.chdir('D:\Copyofconc'), поэтому текущий рабочий каталог должен быть "D:\Copyofconc" .. p >

Теперь, чтобы получить файлы input1.dic и input2.dic, я прочитаю строки "..\conc\input1.dic", затем используйте команду

input1_path = os.path.abspath('..\conc\input1.dic') (для изменения относительного пути к абсолютному пути. Здесь в качестве текущего рабочего каталога находится "D:\Copyofconc", к файлу ".\conc\input1.dic" следует обращаться относительно "D:\Copyofconc" )

поэтому input1_path должен быть "D:\conc\input1.dic"

Ответ 10

Альтернатива, которая работает для меня:

this_dir = os.path.dirname(__file__) 
filename = os.path.realpath("{0}/relative/file.path".format(this_dir))

Ответ 11

Что сработало для меня, используйте sys.path.insert. Затем я указал каталог, в котором мне нужно было идти. Например, мне просто нужно было перейти в один каталог.

import sys
sys.path.insert(0, '../')

Ответ 12

Я не уверен, что это относится к некоторым из более старых версий, но я считаю, что Python 3.3 поддерживает поддержку относительного пути.

Например, следующий код должен создать текстовый файл в той же папке, что и python script:

open("text_file_name.txt", "w+t")

(обратите внимание, что в начале не должно быть прямой или обратной косой черты, если это относительный путь)