Используя Python os.path, как мне перейти на один каталог? - PullRequest
180 голосов
/ 25 марта 2012

Я недавно обновил Django с версии 1.3.1 до версии 1.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, но , поскольку Django 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?

Ответы [ 11 ]

241 голосов
/ 25 марта 2012
os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'templates'))

Что касается папки с шаблонами, я не знаю, так как Django 1.4 только что вышел, и я еще не смотрел на нее. Возможно, вам следует задать еще один вопрос по SE, чтобы решить эту проблему.

Вы также можете использовать normpath для очистки пути вместо abspath. Однако в этой ситуации Django ожидает абсолютный путь, а не относительный путь.

Для кроссплатформенной совместимости используйте os.pardir вместо '..'.

76 голосов
/ 25 марта 2012

Чтобы получить папку с файлом, просто используйте:

os.path.dirname(path) 

Чтобы открыть папку, просто используйте os.path.dirname снова

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

Возможно, вы захотите проверить, является ли __file__ символической ссылкой:

if os.path.islink(__file__): path = os.readlink (__file__)
14 голосов
/ 07 сентября 2012

Вы хотите именно это:

BASE_DIR = os.path.join( os.path.dirname( __file__ ), '..' )
9 голосов
/ 22 апреля 2014

Лично я бы пошел на функциональный подход

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

current_dirs_parent = get_parent_dir(os.getcwd())
7 голосов
/ 25 июля 2018

Если вы используете 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])  # "."
6 голосов
/ 23 августа 2016

Это может быть полезно для других случаев, когда вы хотите перейти на 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   
6 голосов
/ 16 ноября 2015

Я думаю, что самое простое - просто повторно использовать dirname (). Поэтому вы можете позвонить

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

, если файл находится по адресу /Users/hobbes3/Sites/mysite/templates/method.py

Это вернет "/ Users / hobbes3 / Sites / mysite"

6 голосов
/ 21 января 2013
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

В отсутствие символических ссылок оба ответа идентичны.

2 голосов
/ 16 июля 2013

Для параноика, как я, я бы предпочел этот

TEMPLATE_DIRS = (
    __file__.rsplit('/', 2)[0] + '/templates',
)
1 голос
/ 24 апреля 2019

Чтобы перейти 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...