[python] 파이썬의 상대 경로

코드베이스의 몇 가지 템플릿 파일을 현재 디렉토리로 복사하는 간단한 도우미 스크립트를 작성 중입니다. 그러나 템플릿이 저장된 디렉토리의 절대 경로는 없습니다. 스크립트에서 상대 경로가 있지만 스크립트를 호출하면 현재 작업 디렉토리에 상대적인 경로로 처리합니다. 이 상대 URL이 대신 스크립트의 위치에서 오도록 지정하는 방법이 있습니까?



답변

스크립트가있는 파일에서 다음과 같은 작업을 수행하려고합니다.

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

이것은 당신이 찾고있는 파일의 절대 경로를 줄 것입니다. setuptools를 사용하는 경우 패키지 자원 API를 대신 사용해야 합니다.

업데이트 : 여기에 주석에 응답하여 코드 샘플을 붙여 넣을 수 있습니다. 🙂

__file__항상 사용할 수 있는 것은 아니라고 생각하는 것이 맞 습니까 (예 : 파일을 가져 오는 대신 직접 실행하는 경우)?

__main__파일을 직접 실행한다고 언급 할 때 스크립트 를 의미한다고 가정합니다 . 그렇다면 내 시스템 (OS X 10.5.7의 Python 2.5.1)에서는 그렇지 않은 것 같습니다.

#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 컴퓨터에서 예외를 발생시킵니다.


답변

필요합니다 os.path.realpath(아래 샘플은 상위 디렉토리를 경로에 추가합니다)

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


답변

허용 된 답변에서 언급했듯이

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')

경우에 따라 허용 된 답변이 잘못 될 수 있습니다. 자세한 내용은 링크를 참조하십시오


답변

이제 2018 년이며 Python은 이미 __future__오래 전에 진화했습니다 . 어떻게 놀라운 사용에 대한 pathlib작업을 수행하기 위해 파이썬 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
        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)


답변

내 코드를 고려하십시오.

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)


답변

sys.path 참조
프로그램 시작시 초기화 된 대로이 목록의 첫 번째 항목 인 path [0]은 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'


답변

사용하는 대신

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__을 사용하면 모듈이로드 된 파일을 반환하므로 파일에서로드 된 경우 스크립트가있는 파일을 다른 곳에서 호출하면 반환 된 디렉토리가 올바르지 않습니다.

이 답변은 https://stackoverflow.com/a/31867043/5542253https://stackoverflow.com/a/50502/5542253에 대한 자세한 정보를 제공합니다.