파이썬의 os.path를 사용하여 하나의 디렉토리를 어떻게 올라갈 수 있습니까?


224

최근에 Django를 v1.3.1에서 v1.4로 업그레이드했습니다.

내 옛날 settings.py에는

TEMPLATE_DIRS = (
    os.path.join(os.path.dirname( __file__ ), 'templates').replace('\\', '/'),
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)

이 가리 킵니다 /Users/hobbes3/Sites/mysite/templates만, 장고 V1.4는 응용 프로그램 폴더와 같은 수준으로 프로젝트 폴더를 이동하기 때문에 , 내 settings.py파일에 지금 /Users/hobbes3/Sites/mysite/mysite/대신 /Users/hobbes3/Sites/mysite/.

실제로 내 질문은 이제 두 가지입니다.

  1. 어떻게 사용합니까 os.path에서 위의 디렉토리 한 수준에서보고 __file__. 즉, 상대 경로를 사용하여 /Users/hobbes3/Sites/mysite/mysite/settings.py찾고 싶습니다 /Users/hobbes3/Sites/mysite/templates.
  2. 나는 유지되어야한다 template(교차 응용 프로그램 템플릿 같은이 폴더 admin, registration프로젝트에서, 등) /User/hobbes3/Sites/mysite수준 또는에서를 /User/hobbes3/Sites/mysite/mysite?

당신은 그냥 사용 oscd../mysite있습니까? 또는 원하는 명령을 수행하십시오
prelic

@prelic 흠? 이해가 안 돼요 settings.py여러 서버 에서 동일하게 사용하기 때문에 경로 하드 코딩을 피하려고 합니다. 유일한 차이점은 데이터베이스 신임 정보 일 수 있습니다. 나는 os.path문서를 읽고 있었지만 한 디렉토리 위로 올라갈 수있는 명령을 찾을 수 없었습니다. 처럼 cd ...
hobbes3

2
@ hobbes3 전달 될 때만이 아니라 파일 시스템 전체에서 위의 디렉토리를os.path.join( os.path.dirname( __file__ ), '..' ) .. 의미 할 수 있습니다 . cd
Michael Berkowski

3
@Michael, 아마 사용하는 것이 좋습니다os.path.join( os.path.dirname ( __file__), os.path.pardir)
mgilson

답변:


285
os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'templates'))

템플릿 폴더가 있어야하는 한 Django 1.4가 나왔으므로 아직 보지 못했습니다. 이 문제를 해결하기 위해 SE에 대한 다른 질문을해야 할 것입니다.

normpath대신 경로를 정리하는 데 사용할 수도 있습니다 abspath. 그러나이 상황에서 Django는 상대 경로가 아닌 절대 경로를 기대합니다.

플랫폼 간 호환성을 위해 os.pardir대신을 사용하십시오 '..'.


4
사용하는 것이 좋지 ..않습니까? 이 답변이 더 적은 표를 얻는 이유는 무엇입니까?
hobbes3

1
왜 더 적은 표를 받고 있는지 모르겠지만 항상 내가 사용한 것입니다. 의 예에서도 정의되어 normpath있습니다. 또한 심볼릭 링크를 올바르게 통과합니다.
forivall

1
abspath를 사용하면 약간 정리됩니다. 존재하지 않으면 경로 이름의 실제 문자열 /Users/hobbes3/Sites/mysite/mysite/../templates은 완벽하지만 괜찮지 만 조금 더 복잡합니다. 또한 Django의 절대 경로 사용 알림을 준수합니다. 상대 경로를 사용하는 다른 상황에있는 경우 대신 경로를 단순화하기 위해 normpath를 사용해야합니다.
forivall


1
@Zitrax이 플랫폼이 다른 플랫폼을 알고 있거나 향후 안전을 위해 존재하는 플랫폼에 대해 알고 있습니까? (실제로 알지 os.pardir못했고 실제로 os문서 의 맨 아래에 도달하지 못했습니다 )
forivall

98

파일의 폴더를 얻으려면 다음을 사용하십시오.

os.path.dirname(path) 

폴더를 만들려면 os.path.dirname다시 사용 하십시오

os.path.dirname(os.path.dirname(path))

__file__심볼릭 링크 인지 확인하고 싶을 수도 있습니다 .

if os.path.islink(__file__): path = os.readlink (__file__)

17
n통화 os.path.dirname n시간 없이 폴더를 올리는 방법이 있습니까?
Oriol Nieto

9
@OriolNieto 예, Python 3.4+ 버전부터 사용할 수 있습니다 pathlib.Path.parents[levels_up-1]. 더 많은 솔루션을 보려면 이 질문 을 보십시오
jwalton

23

Python 3.4 이상을 사용하는 경우 여러 디렉토리를 위로 이동하는 편리한 방법은 pathlib다음과 같습니다.

from pathlib import Path

full_path = "path/to/directory"
str(Path(full_path).parents[0])  # "path/to"
str(Path(full_path).parents[1])  # "path"
str(Path(full_path).parents[2])  # "."

2
이것은 가장 깨끗한 방법입니다.
hobbes3

18

당신은 이것을 정확히 원합니다 :

BASE_DIR = os.path.join( os.path.dirname( __file__ ), '..' )

9

개인적으로, 나는 기능 접근을 위해 갈 것입니다

def get_parent_dir(directory):
    import os
    return os.path.dirname(directory)

current_dirs_parent = get_parent_dir(os.getcwd())

입력에 후행 슬래시가 포함 된 경우이 답변이 작동하지 않도록주의하십시오. 예 : os.path.dirname('/tmp/lala/')여전히 리턴'/tmp/lala'
Fruit

후행 슬래시 케이스는이 답변을 참조 할 수 있습니다. stackoverflow.com/a/25669963/1074998
Fruit

7

가장 쉬운 방법은 dirname ()을 재사용하는 것입니다.

os.path.dirname(os.path.dirname( __file__ ))

파일이 /Users/hobbes3/Sites/mysite/templates/method.py에있는 경우

"/ Users / hobbes3 / Sites / mysite"를 반환합니다.


6
from os.path import dirname, realpath, join
join(dirname(realpath(dirname(__file__))), 'templates')

최신 정보:

settings.py심볼릭 링크를 통해 "복사"하면 @forivall의 대답이 더 좋습니다.

~user/
    project1/  
        mysite/
            settings.py
        templates/
            wrong.html

    project2/
        mysite/
            settings.py -> ~user/project1/settings.py
        templates/
            right.html

위의 방법은 '본다' wrong.html, @forivall의 방법은right.html

심볼릭 링크가 없으면 두 답변이 동일합니다.


이 방법에 문제가 있습니까? 그것은 잘 작동하고 멋지지만 약간 hackish;)
Gricha

링크를 처리하는 방법에서 허용되는 답변과 약간 다릅니다. 그렇지 않으면 동일합니다.
Antony Hatchkins

6

x 폴더를 위로 이동하려는 다른 경우에 유용 할 수 있습니다. 그냥 실행 walk_up_folder(path, 6)6 개 폴더를 이동합니다.

def walk_up_folder(path, depth=1):
    _cur_depth = 1        
    while _cur_depth < depth:
        path = os.path.dirname(path)
        _cur_depth += 1
    return path   

for _ in xrange(depth)지역 변수를 추적 하는 대신 사용할 수 있습니다 .
Zitrax

2

나 같은 편집증의 경우, 나는 이것을 선호합니다

TEMPLATE_DIRS = (
    __file__.rsplit('/', 2)[0] + '/templates',
)

8
아마도 대신 '/'사용한다os.sep
djhaskin987

1

n폴더를 올리 려면 ... 실행up(n)

import os

def up(n, nth_dir=os.getcwd()):
    while n != 0:
        nth_dir = os.path.dirname(nth_dir)
        n -= 1
    return nth_dir


0

사용하면 os.path우리는 그처럼 한 디렉토리 위로 갈 수 있습니다

one_directory_up_path = os.path.dirname('.')

또한 원하는 디렉토리를 찾은 후 다른 파일 / 디렉토리 경로와 결합 할 수 있습니다

other_image_path = os.path.join(one_directory_up_path, 'other.jpg')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.