2010-05-12 5 views
94

этот код получить шаблоны/blog1/page.html в b.py:Как получить расположение родителя реж

path = os.path.join(os.path.dirname(__file__), os.path.join('templates', 'blog1/page.html')) 

, но я хочу, чтобы получить расположение родителя реж:

и как получить место Кажущаяся

благодаря

обновление:

это право:

dirname=os.path.dirname 
path = os.path.join(dirname(dirname(__file__)), os.path.join('templates', 'blog1/page.html')) 

или

path = os.path.abspath(os.path.join(os.path.dirname(__file__),"..")) 
+2

Итак, вы хотите получить 'blog1' или' a'? И где находится ваш текущий файл? –

+0

Вы понимаете, что делает ваш код? – SilentGhost

+1

да, он получает шаблоны/blog1/page.html – zjm1126

ответ

114

Вы можете применить имя_директории несколько раз, чтобы подняться выше: dirname(dirname(file)). Однако это может быть только до корневого пакета. Если это проблема, используйте os.path.abspath: dirname(dirname(abspath(file))).

+1

он, кажется, знает о 'dirname' – SilentGhost

+29

Я знаю, что OP знает о' dirname'. Для всех не очевидно, что применение dirname к каталогу дает родительский каталог. –

+0

привет Марсело, посмотрите обновленный – zjm1126

3

Может быть, присоединить две папки .., чтобы получить родительский элемент родительской папки?

path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)),"..","..")) 
9
os.path.dirname(os.path.abspath(__file__)) 

Если вам путь к a.

Но если b.py это файл, который в данный момент выполняется, то вы можете достичь того же, просто делая

os.path.abspath(os.path.join('templates', 'blog1', 'page.html')) 
+1

o, я знаю, вы правы, и я хочу получить родительскую папку. как его получить – zjm1126

+0

@ zjm1126: См. ответ Марсело Кантоса. Применяйте 'dirname()' дважды. Все, что вам нужно сейчас, должно быть на этом сайте. –

37

os.path.abspath ничего не проверяет, так что, если мы уже добавления строк в __file__ там нет нужно беспокоиться о dirname или присоединении или любом из них. Просто относиться к __file__ как каталог и начать восхождение:

# climb to __file__'s parent's parent: 
os.path.abspath(__file__ + "/../../") 

Это гораздо менее запутанным, чем os.path.abspath(os.path.join(os.path.dirname(__file__),"..")) и примерно так же, как управляемый dirname(dirname(__file__)). Восхождение на более чем два уровня начинает смеяться.

Но, так как мы знаем, сколько уровней, чтобы подняться, мы могли бы очистить это с простенькой функции:

uppath = lambda _path, n: os.sep.join(_path.split(os.sep)[:-n]) 

# __file__ = "/aParent/templates/blog1/page.html" 
>>> uppath(__file__, 1) 
'/aParent/templates/blog1' 
>>> uppath(__file__, 2) 
'/aParent/templates' 
>>> uppath(__file__, 3) 
'/aParent' 
+0

Мне нравится этот ответ best^ – Stephen

+0

Отличный подход – MA1

+2

Это приятно, но было бы здорово, если бы в стандартной библиотеке добавилась удобная функция, которая достигла этого ... не хочу, чтобы каждый раз приходил к SO каждый раз, когда мне нужен этот func – gradi3nt

2

Простой способ может быть:

import os 
current_dir = os.path.abspath(os.path.dirname(__file__)) 
parent_dir = os.path.abspath(current_dir + "/../") 
print parent_dir 
7

os.pardir является лучшим путь для ../ и более читаемый.

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

Это возвращает родительский путь given_path

0

Я думаю, что использование этого лучше:

os.path.realpath(__file__).rsplit('/', X)[0] 


In [1]: __file__ = "/aParent/templates/blog1/page.html" 

In [2]: os.path.realpath(__file__).rsplit('/', 3)[0] 
Out[3]: '/aParent' 

In [4]: __file__ = "/aParent/templates/blog1/page.html" 

In [5]: os.path.realpath(__file__).rsplit('/', 1)[0] 
Out[6]: '/aParent/templates/blog1' 

In [7]: os.path.realpath(__file__).rsplit('/', 2)[0] 
Out[8]: '/aParent/templates' 

In [9]: os.path.realpath(__file__).rsplit('/', 3)[0] 
Out[10]: '/aParent' 
+0

Не совсем, это зависит от ОС (не будет работать в Windows). Также он не позволяет использовать относительные пути. – kgadek

0

Вот еще относительно простое решение, которое:

  • не используйте dirname() (который работает не так, как ожидалось, на одном уровне аргументов типа file.txt или родственников «..»)
  • не использует abspath() (избегая каких-либо предположений о текущем рабочем каталоге), но вместо этого сохраняет относительный характер путей

он просто использует normpath и join:

def parent(p): 
    return os.path.normpath(os.path.join(p, os.path.pardir)) 

# Example: 
for p in ['foo', 'foo/bar/baz', 'with/trailing/slash/', 
     'dir/file.txt', '../up/', '/abs/path']: 
    print parent(p) 

Результат:

. 
foo/bar 
with/trailing 
dir 
.. 
/abs 
0

Я пробовал:

import os 
os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))), os.pardir)) 
3

Используйте следующие для перехода к предыдущей папке:

os.chdir(os.pardir) 

Если нужно несколько прыжков хорошо и простое решение будет использовать простой декоратор в этом случае.

12

Вы можете использовать pathlib модуль в Python 3.4+:

from pathlib import Path 

Path(__file__).parent 

Вы можете использовать несколько вызовов parent идти дальше по пути:

Path(__file__).parent.parent 

В качестве альтернативы заданию parent дважды , вы можете использовать

Path(__file__).parents[1] 
Смежные вопросы