親ディレクトリの場所を取得する方法


129

このコードは、b.pyのtemplates / blog1 / page.htmlを取得します。

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

しかし、私は親ディレクトリの場所を取得したい:

aParent
   |--a
   |  |---b.py
   |      |---templates
   |              |--------blog1
   |                         |-------page.html
   |--templates
          |--------blog1
                     |-------page.html

とaParentの場所を取得する方法

ありがとう

更新しました:

これは正しいです:

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
だから、取得したいですblog1a?そして、現在のファイルはどこにありますか?
Felix Kling、

あなたのコードが何をしているか理解していますか?
SilentGhost 2010年

1
はい、templates / blog1 / page.htmlを取得します
zjm1126

os.path.join('templates', 'blog1/page.html')私には奇妙に見えます。あなたは物事を混同しています。どちらかos.path.join('templates', 'blog1', 'page.html')または'templates/blog1/page.html'。そして、はるかに簡単になりos.path.abspath(os.path.join('templates', 'blog1', 'page.html'))、その後
フェリックスクリング

1
@zjm:いいえ、あなたはありません取得、そのページを。テンプレートファイルを取得するために使用できるのは、ブラックボックスではありません。それは一連の些細な小さなステップを実行します、そしてあなたがそれらを理解できれば、あなたはこの質問を持っていないでしょう。
SilentGhost 2010年

回答:


171

dirnameを繰り返し適用して、より高く登ることができますdirname(dirname(file))。ただし、これはルートパッケージまでしか実行できません。これが問題である場合は、次を使用しos.path.abspathますdirname(dirname(abspath(file)))


37
OPが知っていることを知っていdirnameます。dirnameをディレクトリに適用すると親ディレクトリが生成されることは誰にとっても明白ではありません。
Marcelo Cantos

4
dirname常に親ディレクトリを返すわけではありませんtwitter.com/#!/ActiveState/status/671049326788608
Sridhar Ratnakumar 2010年

2
@Sridhar:それはあなたの視点に依存します。末尾のパス/がリーフディレクトリエントリ自体を表すものではなく、その内容であると考えています。そのため、たとえば、mv xxx yyy/yyy既存のディレクトリでない場合は失敗します。いずれにせよ、私たちがあなたの主張を与えられたものとして取り上げたとしても、それは私の答えの文脈には関係ありません。fileもの結果もdirnameで終わりません/
Marcelo Cantos、2010年

1
細かい修正:dirnameが返さ'/'れることがあり/ます。それが唯一の例外です、私の知る限り。
Marcelo Cantos、2013

55

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__))。3つ以上のレベルを登ると、ばかげたことになります。

しかし、登るレベルがいくつあるかわかっているので、単純な小さな関数でこれをクリーンアップできます。

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'

2
これはいいですが、標準ライブラリにこれを実現する便利な関数が追加されていればクールです...私がこの関数を必要とするたびにSOに来たくない
gradi3nt

4
os.path.abspath(os.path.join(__file__, "..", "..")、より移植可能に?
slowD 2018

40

Python 3.4以降のモジュールで相対パスを使用しpathlibます。

from pathlib import Path

Path(__file__).parent

複数の呼び出しを使用parentして、パスをさらに進むことができます。

Path(__file__).parent.parent

parent2回指定する代わりに、以下を使用できます。

Path(__file__).parents[1]

2
パスを変更するために文字列として必要な場合は、を使用できますstr(Path(__file__).parent)
フィリップ

12
os.path.dirname(os.path.abspath(__file__))

へのパスを提供する必要がありますa

しかし、b.py現在実行されているファイルの場合、次のようにするだけで同じことができます

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

1
o、私は知っている、あなたは正しい、そして私はaの親フォルダを取得したい。入手方法
zjm1126

@ zjm1126:Marcelo Cantosの回答を参照してください。dirname()2回塗ります。今必要なものはすべてこのサイトにあるはずです。
フェリックスクリング

9

os.pardir../より読みやすくするためのより良い方法です。

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

これは、given_pathの親パスを返します


5

簡単な方法は次のとおりです。

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

3

..親フォルダの親を取得するために、2つのフォルダを結合できますか?

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

3

次のコマンドを使用して、前のフォルダーにジャンプします。

os.chdir(os.pardir)

複数のジャンプが必要な場合、この場合は簡単なデコレータを使用するのが良い簡単な解決策です。


1

次に、比較的簡単な別のソリューションを示します。

  • 使用しないdirname()(「file.txt」などの1レベルの引数または「..」などの相対親では期待どおりに機能しない)
  • abspath()(現在の作業ディレクトリに関する想定を避けて)使用せず、代わりにパスの相対文字を保持します

それは単に使用しnormpathjoin

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

私はこれを使う方が良いと思います:

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'

いいえ、OSに依存しています(Windowsでは機能しません)。また、相対パスを使用することもできません。
kgadek 2014年

それはひどい解決策です。すべてのOSで機能しない
web.learner

0

私は試した:

import os
os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))), os.pardir))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.