파이썬에서 상대 위치에서 파일 열기


132

python 코드가 이전 windows 디렉토리 'main'에 의해 알려지지 않고 실행되고 코드가 실행될 때 설치되는 모든 위치에서 'main / 2091 / data.txt'디렉토리에 액세스해야한다고 가정하십시오.

open (location) 기능을 어떻게 사용해야합니까? 위치는 무엇입니까?

편집하다 :

아래의 간단한 코드가 작동한다는 것을 알았습니다. 단점이 있습니까?

    file="\2091\sample.txt"
    path=os.getcwd()+file
    fp=open(path,'r+');

1
이스케이프 처리되지 않은 백 슬래시를 사용하고 있습니다. 한 가지 단점이 있습니다.
orip

6
몇 가지 단점. 1) @orip에 따라 창에서도 경로에 슬래시를 사용하십시오. 문자열이 작동하지 않습니다. 또는와 같은 원시 문자열을 사용하십시오 r"\2091\sample.txt". 또는 그들을 피하십시오 "\\2091\\sample.txt"(그러나 그것은 성가시다). 또한 2) 스크립트를 실행할 때 있었던 경로 인 getcwd ()를 사용하고 있습니다. 스크립트 위치를 기준으로 원한다고 생각했지만 지금은 궁금합니다. 3) 항상 os.path경로 조작을위한 기능을 사용하십시오 . 경로 연결 라인은 os.path.join(os.getcwd(), file)4) 이어야 합니다. 의미가 없다
Russ

3
그리고 좋은 측정을 위해 ... 5) 컨텍스트 가드를 사용하여 파일을 깨끗하게 유지하고 파일을 닫는 것을 잊지 마십시오 with open(path, 'r+') as fp:. 내가 본 진술 에 대한 최고의 설명은 여기 를 참조 하십시오with .
Russ

표시된대로 슬래시에 필요한주의 옆 os.path.abspath에 열려있는 상대 경로의 전체 경로를 쉽게 얻는 기능 이 있습니다. 최종 진술은 다음과 같습니다 :os.path.abspath('./2091/sample.txt')
OPMendeavor

답변:


189

이 유형의 작업으로 실제 작업 디렉토리가 무엇인지주의해야합니다. 예를 들어, 파일이있는 디렉토리에서 스크립트를 실행할 수 없습니다.이 경우 상대 경로 만 사용할 수는 없습니다.

원하는 파일이 스크립트가 실제로 위치한 하위 디렉토리에 있다고 확신하면 __file__여기에서 도움을 줄 수 있습니다. __file__실행중인 스크립트가있는 전체 경로입니다.

따라서 다음과 같이 바이올린을 칠 수 있습니다.

import os
script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)

아래의 간단한 코드가 작동한다는 것을 알았습니다. 단점이 있습니까? <pre> file = "\ sample.txt"path = os.getcwd () + str (loc) + file fp = open (path, 'r +'); <code>

@Arash 단점은 cwd (현재 작업 디렉토리)가 될 수 있으며 스크립트가있는 위치 일 필요는 없습니다.
코리 Mawhorter

5
__file__상대 경로 (적어도 어떤 이유로 내 설정에서)이므로 os.path.abspath(__file__)먼저 전화해야합니다 . osx / homebrew 2.7
Cory Mawhorter

2
os.path.dirname ( file )이 Python 2.7에서 작동하지 않습니다. 그것은 보여주고있다NameError: name '__file__' is not defined
Soumendra

1
@ Soumendra 나는 당신이 콘솔에서 그것을 시도하고 있다고 생각합니다. * .py 파일에서 사용해보십시오.
Enku December

35

이 코드는 잘 작동합니다.

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)

나를 위해 현재 폴더의 상위 폴더에있는 파일에 액세스 할 수 없습니다. ..가 문자열로 추가됩니다.
M. Paul

Windows에서 작동하지 않았습니다. 파일 경로는 정확하지만 파이썬은 "파일을 찾을 수 없습니다"라고 말하고 \\ 구분 기호가있는 경로를 보여줍니다.
lonstar

26

Russ의 원래 답변에서 찾은 불일치를 명확히 할 수 있도록 계정을 만들었습니다.

참고로 그의 원래 답변은 다음과 같습니다.

import os
script_dir = os.path.dirname(__file__)
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)

원하는 파일에 대한 절대 시스템 경로를 동적으로 만들려고하므로 큰 대답입니다.

Cory Mawhorter __file__는 상대 경로 (내 시스템에도 있음)를 발견하고을 사용하도록 제안했습니다 os.path.abspath(__file__). os.path.abspath그러나, 현재 스크립트의 절대 경로를 반환 (예 /path/to/dir/foobar.py)

이 방법을 사용하려면 (그리고 결국 어떻게 작동하는지) 경로 끝에서 스크립트 이름을 제거해야합니다.

import os
script_path = os.path.abspath(__file__) # i.e. /path/to/dir/foobar.py
script_dir = os.path.split(script_path)[0] #i.e. /path/to/dir/
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)

결과 abs_file_path (이 예에서)는 다음과 같습니다. /path/to/dir/2091/data.txt


14
더 간단한 두 가지 방법을 결합 할 수도 있습니다os.path.dirname(os.path.abspath(__file__))
Luke Taylor

1
@LukeTaylor 사실 os.path.dirname작년에 대답했던 것처럼 기능을 직접 복제하는 것보다 낫습니다 .
그랜트 훌 가드

19

사용중인 운영 체제에 따라 다릅니다. Windows와 * nix 모두와 호환되는 솔루션을 원한다면 다음과 같습니다.

from os import path

file_path = path.relpath("2091/data.txt")
with open(file_path) as f:
    <do stuff>

잘 작동합니다.

path모듈은 운영 체제에 관계없이 경로를 포맷 할 수 있습니다. 또한 파이썬은 올바른 권한이있는 한 상대 경로를 잘 처리합니다.

편집 :

의견에서 kindall이 언급했듯이, 파이썬은 어쨌든 유닉스 스타일과 윈도우 스타일 경로를 변환 할 수 있으므로 간단한 코드조차도 작동합니다.

with open("2091/data/txt") as f:
    <do stuff>

즉, path모듈 에는 여전히 유용한 기능이 있습니다.


3
relpath()경로 이름을 상대 경로로 변환합니다. 이미 상대 경로이므로 아무 것도 수행하지 않습니다.
kindall

적절한 경우 유닉스 스타일 경로에서 Windows 스타일 경로로 변환합니다. os.path더 나은 선택이 될 다른 기능이 모듈에 있습니까?
Wilduck

1
Windows는 이미 UNIX 스타일 경로에서 제대로 작동합니다. 적어도 NT 기반 시리즈는 (2000, XP, Vista, 7)입니다. 변환이 필요하지 않습니다.
kindall

7
이 답변은 정확하지 않으며 문제를 일으킬 것입니다. 상대 경로는 기본적으로 현재 작업 디렉토리 (스크립트가 실행 된 경로)에 상대적이며 실제 스크립트 위치는 아닙니다. 를 사용해야 __file__합니다. 내 대답을 참조하십시오.
Russ

이 답변의 작성자가 os.path.relpath를 os.path.abspath와 혼동 했습니까?
foobarbecue

15

Windows 시스템에서 코드가 Python 3을 실행하는 파일을 찾을 수없는 이유를 찾기 위해 많은 시간을 소비합니다. 그래서 나는 추가했다. 이전과 모든 것이 잘 작동했습니다.

import os

script_dir = os.path.dirname(__file__)
file_path = os.path.join(script_dir, './output03.txt')
print(file_path)
fptr = open(file_path, 'w')

더 나은 :file_path = os.path.join(script_dir, 'output03.txt')
Mr_and_Mrs_D

Windows OS를 사용해 보았지만 성공하지 못했습니다.
Ângelo Polotto

흥미 롭습니다-script_dir을 인쇄 할 수 있습니까? 다음과 같이 절대 경로로 설정하십시오script_dir = os.path.abspath(os.path.dirname(__file__))
Mr_and_Mrs_D

시도하면 성공하면 답을 바꿀 것입니다.
Ângelo Polotto

6

암호:

import os
script_path = os.path.abspath(__file__) 
path_list = script_path.split(os.sep)
script_directory = path_list[0:len(path_list)-1]
rel_path = "main/2091/data.txt"
path = "/".join(script_directory) + "/" + rel_path

설명:

라이브러리 가져 오기 :

import os

__file__현재 스크립트 경로를 얻는 데 사용하십시오 .

script_path = os.path.abspath(__file__)

스크립트 경로를 여러 항목으로 구분합니다.

path_list = script_path.split(os.sep)

목록에서 마지막 항목 (실제 스크립트 파일)을 제거하십시오.

script_directory = path_list[0:len(path_list)-1]

상대 파일의 경로를 추가하십시오.

rel_path = "main/2091/data.txt

목록 항목을 결합하고 상대 경로 파일을 추가하십시오.

path = "/".join(script_directory) + "/" + rel_path

이제 다음과 같이 파일로 원하는 것을 수행하도록 설정되었습니다.

file = open(path)

대신에 path = "/".join(script_directory) + "/" + rel_pathos 모듈을 사용해야합니다 path = os.path.join(script_directory, rel_path). 대신 수동으로 사용되어야하는 경로의 구문 분석script_path = os.path.dirname(__file__)
Mr_and_Mrs_D

3

파일이 상위 폴더에있는 경우 (예 : follower.txt, 간단히 사용할 수 있습니다open('../follower.txt', 'r').read()


3

이 시도:

from pathlib import Path

data_folder = Path("/relative/path")
file_to_open = data_folder / "file.pdf"

f = open(file_to_open)

print(f.read())

Python 3.4는 pathlib라는 파일과 경로를 처리하기위한 새로운 표준 라이브러리를 도입했습니다. 그것은 나를 위해 작동합니다!


2

이것이 어디에서나 작동하는지 확실하지 않습니다.

우분투에서 ipython을 사용하고 있습니다.

현재 폴더의 하위 디렉토리에서 파일을 읽으려면

/current-folder/sub-directory/data.csv

스크립트가 현재 폴더에 있으므로 간단히 다음을 시도하십시오.

import pandas as pd
path = './sub-directory/data.csv'
pd.read_csv(path)

1

파이썬은 파일 이름을 운영 체제에 전달하면 열립니다. 운영 체제가 main/2091/data.txt(힌트 :) 와 같은 상대 경로를 지원 하면 제대로 작동합니다.

이와 같은 질문에 대답하는 가장 쉬운 방법은 시도하고 어떤 일이 일어나는지 보는 것입니다.


2
사실이 아니다 ... 스크립트 내부의 작업 디렉토리는,에서 스크립트를 실행 한 위치 하지 스크립트의 위치. 다른 곳에서 스크립트를 실행하면 (스크립트가 시스템 경로에있을 수 있음) 서브 디렉토리에 대한 상대 경로가 작동하지 않습니다. 이 문제를 해결하는 방법에 대한 내 답변을 참조하십시오.
Russ

@Russ-OP의 예는을 사용합니다 getcwd(). 나는 원래의 설명을 "코드가 어디에 있는지에 관계없이 스크립트를 실행하는 위치와 관련하여"읽었다.
orip

@orip-OP는 질문 후 3 시간 후에 getcwd () 호출을 추가했습니다. 상관없이. :)
Russ

1
import os
def file_path(relative_path):
    dir = os.path.dirname(os.path.abspath(__file__))
    split_path = relative_path.split("/")
    new_path = os.path.join(dir, *split_path)
    return new_path

with open(file_path("2091/data.txt"), "w") as f:
    f.write("Powerful you have become.")

0

내가 초보자 였을 때 나는이 설명들이 약간 겁이났다는 것을 알았다. 처음에 시도 할 것 For Windows

f= open('C:\Users\chidu\Desktop\Skipper New\Special_Note.txt','w+')
print(f) 

그리고 이것은 syntax error. 나는 혼란스러워했다. 그런 다음 Google에서 서핑을 한 후. 오류가 발생한 이유를 찾았습니다. 초보자를위한 글쓰기

경로를 유니 코드로 읽으려면 \파일 경로를 시작할 때 간단히 추가하십시오.

f= open('C:\\Users\chidu\Desktop\Skipper New\Special_Note.txt','w+')
print(f)

이제 \디렉토리를 시작하기 전에 추가 만하면 됩니다.


1
백 슬래시는 여러 문자의 이스케이프 문자입니다. \t예 를 들어와 같은 \top\directory경우 '\ t'가 탭 문자로 해석되어 '트릭'이 실패합니다. 가장 좋은 방법은 r'C:\Users\chidu\Desktop\Skipper New\Special_Note.txt'문자를 '이스케이프'하지 않는 원시 문자열 형식을 사용하는 것 입니다.
로널드
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.