Я создаю простой вспомогательный скрипт для работы, который скопирует пару файлов шаблонов из нашей базы кода в текущий каталог. Однако у меня нет абсолютного пути к каталогу, в котором хранятся шаблоны. У меня есть относительный путь из скрипта, но когда я вызываю скрипт, он обрабатывает его как путь относительно текущего рабочего каталога. Есть ли способ указать, что этот относительный URL-адрес относится к местоположению скрипта?
Переведено автоматически
Ответ 1
В файле, содержащем скрипт, вы хотите сделать что-то вроде этого:
import os dirname = os.path.dirname(__file__) filename = os.path.join(dirname, 'relative/path/to/file/you/want')
Это даст вам абсолютный путь к файлу, который вы ищете. Обратите внимание, что если вы используете setuptools, вам, вероятно, следует использовать его package resources API вместо этого.
ОБНОВЛЕНИЕ: я отвечаю на комментарий здесь, чтобы я мог вставить пример кода. :-)
Правильно ли я понимаю, что __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__ расширениями on 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
Сейчас 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's 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()
В будущем все будет именно так просто.
Более того, мы можем выбирать, проверять и копировать / перемещать эти файлы шаблонов с помощью 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 ifnot 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)
Ответ 3
вам нужно os.path.realpath (приведенный ниже пример добавляет родительский каталог к вашему пути)