파이썬에서 부모 디렉토리를 어떻게 얻습니까?


350

누군가 크로스 플랫폼 방식으로 파이썬에서 경로의 부모 디렉토리를 얻는 방법을 말해 줄 수 있습니까? 예 :

C:\Program Files ---> C:\

C:\ ---> C:\

디렉토리에 상위 디렉토리가 없으면 디렉토리 자체를 리턴합니다. 질문은 간단 해 보이지만 Google을 통해 파헤칠 수 없습니다.

답변:


481

Python 3.4에서 업데이트

pathlib모듈을 사용하십시오 .

from pathlib import Path
path = Path("/here/your/path/file.txt")
print(path.parent)

이전 답변

이 시도:

import os.path
print os.path.abspath(os.path.join(yourpath, os.pardir))

yourpath부모가 원하는 경로는 어디 입니까?


137
당신의 대답은 정확하지만 복잡합니다. 보다 더 복잡한 os.path.dirname것처럼 이것에 대한 함수입니다 . 이 질문은 존재하는지 또는 심볼릭 링크가 방해 받았다고 가정 하는 실제 부모 디렉토리 가 아닌 부모 디렉토리 만 요청했습니다 . a+=5-4a+=1
tzot

16
그것은이다 os.pardir,하지 os.path.pardir.
bouteillebleu

9
@bouteillebleu : 모두 os.pardir와 것은 os.path.pardir(그들이 동일) 실제로 정확합니다.
Eric O Lebigot

45
@tzot : 불행히도 os.path.dirname후행 슬래시가 경로에 포함되는지 여부에 따라 다른 결과를 제공합니다. 신뢰할 수있는 결과를 원하면 os.path.join위 의 방법으로 방법 을 사용해야합니다 .
Artfunkel

21
이것은 StackOverflow 질문을 보장하기에 충분히 복잡하기 때문에 이것이 내장 함수로 os.path 라이브러리에 추가되어야한다고 생각합니다.
12 분 44 초

324

사용 os.path.dirname:

>>> os.path.dirname(r'C:\Program Files')
'C:\\'
>>> os.path.dirname('C:\\')
'C:\\'
>>>

주의 사항 : os.path.dirname()후행 슬래시가 경로에 포함되는지 여부에 따라 다른 결과를 제공합니다. 이것은 원하는 의미론 일 수도 있고 아닐 수도 있습니다. Cf. @ 켄더의 대답을 사용하십시오 os.path.join(yourpath, os.pardir).


6
os.path.dirname(r'C:\Program Files')뭐? 파이썬은 'Program Files'파일이있는 디렉토리를 제공합니다. 더군다나, 존재하지 않아도됩니다 : os.path.dirname(r'c:\i\like\to\eat\pie')출력'c:\\i\\like\\to\\eat'
Nick T

41
원래 포스터에는 디렉토리가 존재해야한다고 명시되어 있지 않습니다. 문자열 조작 만하는 경로명 메소드가 많이 있습니다. 경로 이름이 실제로 존재하는지 확인하려면 디스크 액세스가 필요합니다. 응용 프로그램에 따라 이것은 바람직하거나 바람직하지 않을 수 있습니다.
Wai Yip Tung

10
이 솔루션은 후행 os.sep에 민감합니다. os.sep == '/'라고 말하십시오. dirname (foo / bar)-> foo, 그러나 dirname (foo / bar /)-> foo / bar
marcin

6
의도적으로 설계된 것입니다. 후행 /으로 경로를 해석합니다. "path1"이 "path1 /"과 같다고 생각하십니까? 도서관은 가장 일반적인 해석을 사용합니다. 어떤 맥락에서 사람들은 그것들을 동등한 것으로 취급하기를 원할 수 있습니다. 이 경우 먼저 rstrip ( '/')을 수행 할 수 있습니다. 도서관이 다른 해석을 골랐다면 충실도를 잃을 것입니다.
Wai Yip Tung

3
@Ryan, 나는 그것에 대해 모른다. URI의 상대 경로 문제와 후행 /의 유무에 대한 모든 미묘한 문제를 해결하기 위해 작성된 전체 RFC 1808이 있습니다. 일반적으로 동등한 것으로 취급되어야한다는 문서를 알고있는 경우이를 지적하십시오.
Wai Yip Tung

112

Pathlib 메소드 (Python 3.4+)

from pathlib import Path
Path('C:\Program Files').parent
# Returns a Pathlib object

전통적인 방법

import os.path
os.path.dirname('C:\Program Files')
# Returns a string


어떤 방법을 사용해야합니까?

다음과 같은 경우 전통적인 방법을 사용하십시오.

  • Pathlib 객체를 사용하는 경우 기존 코드 생성 오류가 걱정됩니다. Pathlib 객체는 문자열과 연결할 수 없습니다.

  • 파이썬 버전이 3.4 미만입니다.

  • 줄이 필요하고 줄을 받았습니다. 예를 들어 파일 경로를 나타내는 문자열이 있고 부모 디렉토리를 가져와 JSON 문자열에 넣을 수 있다고 가정하십시오. Pathlib 객체로 변환하고 다시 되 돌리는 것은 어리석은 일입니다.

위의 어느 것도 적용되지 않으면 Pathlib를 사용하십시오.



Pathlib는 무엇입니까?

Pathlib이 무엇인지 모르는 경우 Pathlib 모듈은 파일 작업을 훨씬 쉽게 만들어주는 훌륭한 모듈입니다. 대부분의 경우 파일로 작동하는 모든 내장 Python 모듈은 Pathlib 객체와 문자열을 모두 허용합니다. Pathlib 문서 에서 Pathlib로 할 수있는 몇 가지 깔끔한 작업을 보여주는 몇 가지 예를 강조 했습니다.

디렉토리 트리 내에서 탐색 :

>>> p = Path('/etc')
>>> q = p / 'init.d' / 'reboot'
>>> q
PosixPath('/etc/init.d/reboot')
>>> q.resolve()
PosixPath('/etc/rc.d/init.d/halt')

쿼리 경로 속성 :

>>> q.exists()
True
>>> q.is_dir()
False

4
이것이 유일한 정답입니다. Python 2 pip install pathlib2를 사용해야한다면 백 포트를 사용하십시오.
Navin

1
이 솔루션은 후행에 민감하지 않습니다 os.sep!
Dylan F

35
import os
p = os.path.abspath('..')

C:\Program Files ---> C:\\\

C:\ ---> C:\\\


7
이것은 OP가 요청한 임의의 경로의 부모가 아닌 CWD의 부모 만 가져옵니다.
Sergio

당신의 URL의 끝에 두 점을 추가하며 예를 작동 os.path.abspath(r'E:\O3M_Tests_Embedded\branches\sw_test_level_gp\test_scripts\..\..') 결과 :E:\\O3M_Tests_Embedded\\branches
Arindam Roychowdhury에게

이는 다음을 의미 /합니다..
loretoparisi

26

@kender의 대체 솔루션

import os
os.path.dirname(os.path.normpath(yourpath))

yourpath부모가 원하는 경로는 어디 입니까?

그러나이 솔루션은 yourpath빈 문자열이나 점이있는 경우를 처리하지 않기 때문에 완벽하지 않습니다 .

이 다른 솔루션은이 코너 케이스를보다 잘 처리합니다.

import os
os.path.normpath(os.path.join(yourpath, os.pardir))

다음은 찾을 수있는 모든 경우에 대한 출력입니다 (입력 경로는 상대적입니다).

os.path.dirname(os.path.normpath('a/b/'))          => 'a'
os.path.normpath(os.path.join('a/b/', os.pardir))  => 'a'

os.path.dirname(os.path.normpath('a/b'))           => 'a'
os.path.normpath(os.path.join('a/b', os.pardir))   => 'a'

os.path.dirname(os.path.normpath('a/'))            => ''
os.path.normpath(os.path.join('a/', os.pardir))    => '.'

os.path.dirname(os.path.normpath('a'))             => ''
os.path.normpath(os.path.join('a', os.pardir))     => '.'

os.path.dirname(os.path.normpath('.'))             => ''
os.path.normpath(os.path.join('.', os.pardir))     => '..'

os.path.dirname(os.path.normpath(''))              => ''
os.path.normpath(os.path.join('', os.pardir))      => '..'

os.path.dirname(os.path.normpath('..'))            => ''
os.path.normpath(os.path.join('..', os.pardir))    => '../..'

입력 경로는 절대적입니다 (Linux 경로) :

os.path.dirname(os.path.normpath('/a/b'))          => '/a'
os.path.normpath(os.path.join('/a/b', os.pardir))  => '/a'

os.path.dirname(os.path.normpath('/a'))            => '/'
os.path.normpath(os.path.join('/a', os.pardir))    => '/'

os.path.dirname(os.path.normpath('/'))             => '/'
os.path.normpath(os.path.join('/', os.pardir))     => '/'

특히 플랫폼 간 작업을 수행 할 때는 경로를 정규화하는 것이 좋습니다.
DevPlayer

이것이 정답입니다! 상대 경로를 상대적으로 유지합니다. 감사!
Maxim

orginal 한 솔루션은 하나의 사건을 처리하지 않기 때문에이 솔루션은 완벽하지이었다 @Maxim, 나는 그것을 개선 않았다
benjarobin

@ benjarobin 네, 코너 케이스는 생각하지 못했습니다. 감사.
Maxim

18
os.path.split(os.path.abspath(mydir))[0]

디렉토리에 대한 경로에는 작동하지 않으며 디렉토리를 다시 반환합니다.
Anthony Briggs

2
@ AnthonyBriggs, 우분투 12.04에서 Python 2.7.3을 사용하여 이것을 시도했지만 정상적으로 작동하는 것 같습니다. 예상대로 os.path.split(os.path.abspath("this/is/a/dir/"))[0]반환합니다 '/home/daniel/this/is/a'. 나는 현재 거기에서 확인할 Windows 상자가 없습니다. 보고 한 동작을 관찰 한 설정은 무엇입니까?
Dan Menes

당신은 할 수 있습니다 parentdir = os.path.split(os.path.apspath(dir[:-1]))[0]. 마지막에 슬래시가 있으면 제거되기 때문에 이것은 확실합니다. 슬래시가 없으면 앞의 슬래시로 인해 경로의 마지막 부분이 한 문자 길이 인 경우에도 여전히 작동합니다. 물론 이것은 경로가 적절하고 같은 말을하지 않는 것이 가정 /a//b/c///d////당신은 같은 것을 할 때 특히 대부분의 경우 그들은 (적절한)되는, (유닉스에서이 여전히 유효) os.path.abspath또는 기타 os.path기능.
dylnmc

또한 끝에 많은 슬래시를 방지하기 위해 작은 슬래시를 작성하여 제거 할 수 있습니다. 나는 그것을 할 수있는 영리한 1 라이너가있을 수도 있고, 한 줄로 os.path.split을 할 수도 있다고 확신합니다.
dylnmc

@ Den Menes 난 당신이 의견을 보았다. cd / dev /`or ; os.path.split("a/b//c/d///")와 같은 것이 있으면 작동하지 않습니다 . 이것들은 모두 리눅스에서 유효합니다. 방금 이것을 생각해 냈지만 유용 할 수도 있습니다 . (이것은 본질적으로 슬래시가 아닌 마지막을 검색하고 해당 문자까지 경로의 하위 문자열을 가져옵니다.) 앞서 언급 한 명령문을 사용 하고 실행했습니다 . cd //////dev////// is equivalent to cd /devos.path.split(path[:tuple(ind for ind, char in enumerate(path) if char != "/" and char != "\\")[-1]])[0]path = "/a//b///c///d////"'/a//b///c'
dylnmc

14
os.path.abspath(os.path.join(somepath, '..'))

관찰 :

import posixpath
import ntpath

print ntpath.abspath(ntpath.join('C:\\', '..'))
print ntpath.abspath(ntpath.join('C:\\foo', '..'))
print posixpath.abspath(posixpath.join('/', '..'))
print posixpath.abspath(posixpath.join('/home', '..'))

7
import os
print"------------------------------------------------------------"
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
print("example 1: "+SITE_ROOT)
PARENT_ROOT=os.path.abspath(os.path.join(SITE_ROOT, os.pardir))
print("example 2: "+PARENT_ROOT)
GRANDPAPA_ROOT=os.path.abspath(os.path.join(PARENT_ROOT, os.pardir))
print("example 3: "+GRANDPAPA_ROOT)
print "------------------------------------------------------------"

6

당신이 원하는 경우 에만 이름 인수 및 제공 파일의 바로 부모 폴더의 하지 절대 경로 해당 파일을 :

os.path.split(os.path.dirname(currentDir))[1]

즉, currentDir값이/home/user/path/to/myfile/file.ext

위의 명령은 다음을 반환합니다.

myfile


3
os.path.basename (os.path.dirname (current_dir))도 여기에서 작동합니다.
DevPlayer

4
>>> import os
>>> os.path.basename(os.path.dirname(<your_path>))

예를 들어 우분투에서 :

>>> my_path = '/home/user/documents'
>>> os.path.basename(os.path.dirname(my_path))
# Output: 'user'

예를 들어 Windows의 경우 :

>>> my_path = 'C:\WINDOWS\system32'
>>> os.path.basename(os.path.dirname(my_path))
# Output: 'WINDOWS'

두 예제 모두 Python 2.7에서 시도했습니다.


3
import os.path

os.path.abspath(os.pardir)

이것은 일반적으로 상위 디렉토리가 아닌 "현재 작업 디렉토리"의 상위 디렉토리를 원한다고 가정합니다.
DevPlayer

3

다음과 같은 디렉토리 구조가 있다고 가정하십시오.

1]

/home/User/P/Q/R

우리는 디렉토리 R에서 "P"의 경로에 접근하고 싶다.

ROOT = os.path.abspath(os.path.join("..", os.pardir));

2]

/home/User/P/Q/R

디렉토리 R에서 "Q"디렉토리의 경로에 액세스하고 싶을 때

ROOT = os.path.abspath(os.path.join(".", os.pardir));

2

Tung의 답변에 무언가를 추가하기 만하면됩니다 ( rstrip('/')유닉스 상자에 있으면 더 안전한면을 사용해야합니다).

>>> input = "../data/replies/"
>>> os.path.dirname(input.rstrip('/'))
'../data'
>>> input = "../data/replies"
>>> os.path.dirname(input.rstrip('/'))
'../data'

그러나 rstrip('/')입력을 사용하지 않으면을 사용하지 않으면

>>> input = "../data/replies/"

출력

>>> os.path.dirname(input)
'../data/replies'

이는 당신이 모두를 원하는대로에서 무엇을 찾고있어 아마하지 않습니다 "../data/replies/""../data/replies"같은 방식으로 작동 할 수 있습니다.


1
"입력"을 변수 / 참조로 사용하지 않는 것이 좋습니다. 내장 기능입니다.
DevPlayer

2
import os

dir_path = os.path.dirname(os.path.realpath(__file__))
parent_path = os.path.abspath(os.path.join(dir_path, os.pardir))

1
print os.path.abspath(os.path.join(os.getcwd(), os.path.pardir))

이것을 사용하여 py 파일의 현재 위치의 부모 디렉토리를 얻을 수 있습니다.


2
이 제안은 종종 버그로 이어집니다. os.getcwd ()는 종종 "py 파일"이있는 곳이 아닙니다. 패키지를 생각하십시오. "some_package_with_subpackages"를 가져 오면 많은 모듈이 해당 패키지의 최상위 디렉토리에 없습니다. os.getcwd ()는 최상위 스크립트 실행 위치를 반환합니다. 그리고 그것은 또한 명령 줄에서 수행한다고 가정합니다.
DevPlayer

0

부모 디렉토리 경로 가져 오기새 디렉토리 만들기 (이름 new_dir)

부모 디렉토리 경로 가져 오기

os.path.abspath('..')
os.pardir

실시 예 1

import os
print os.makedirs(os.path.join(os.path.dirname(__file__), os.pardir, 'new_dir'))

실시 예 2

import os
print os.makedirs(os.path.join(os.path.dirname(__file__), os.path.abspath('..'), 'new_dir'))


0
import os

def parent_filedir(n):
    return parent_filedir_iter(n, os.path.dirname(__file__))

def parent_filedir_iter(n, path):
    n = int(n)
    if n <= 1:
        return path
    return parent_filedir_iter(n - 1, os.path.dirname(path))

test_dir = os.path.abspath(parent_filedir(2))

0

위에 주어진 대답은 모두 하나 또는 두 개의 디렉토리 레벨로 올라가는 데는 완벽하지만, 디렉토리 트리를 여러 레벨 (예 : 5 또는 10)로 탐색해야하는 경우 약간 번거로울 수 있습니다. N os.pardir의의 목록에 가입하면 간결하게 수행 할 수 있습니다 os.path.join. 예:

import os
# Create list of ".." times 5
upup = [os.pardir]*5
# Extract list as arguments of join()
go_upup = os.path.join(*upup)
# Get abspath for current file
up_dir = os.path.abspath(os.path.join(__file__, go_upup))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.