코드베이스의 몇 가지 템플릿 파일을 현재 디렉토리로 복사하는 간단한 도우미 스크립트를 작성 중입니다. 그러나 템플릿이 저장된 디렉토리의 절대 경로는 없습니다. 스크립트에서 상대 경로가 있지만 스크립트를 호출하면 현재 작업 디렉토리에 상대적인 경로로 처리합니다. 이 상대 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/5542253 및 https://stackoverflow.com/a/50502/5542253에 대한 자세한 정보를 제공합니다.