Pythonのos.pathを使用して、1つのディレクトリに移動するにはどうすればよいですか?


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、Django v1.4はプロジェクトフォルダーをアプリフォルダーと同じレベルに移動しため、私のsettings.pyファイルはでは/Users/hobbes3/Sites/mysite/mysite/なくになりました/Users/hobbes3/Sites/mysite/

だから実際に私の質問は2つになりました:

  1. os.pathから1つ上のレベルのディレクトリを見るにはどうすればよいですか__file__。つまり、相対パスで/Users/hobbes3/Sites/mysite/mysite/settings.py検索/Users/hobbes3/Sites/mysite/templatesしたい。
  2. 私は維持されなければならないtemplate(クロスアプリテンプレートなどがあるフォルダadminregistrationプロジェクトでは、など)/User/hobbes3/Sites/mysiteのレベルかでは/User/hobbes3/Sites/mysite/mysite

カントあなただけの使用oscdしますか../mysite?または、任意のコマンド
prelic

@prelicうーん?わかりません。settings.py複数のサーバーで同じものを使用しているため、パスをハードコーディングしないようにしています。唯一の違いは、データベース資格情報です。os.pathドキュメントを読んでいましたが、1つ上のディレクトリに移動するコマンドが見つかりませんでした。のようにcd ..
hobbes3 2012年

2
@ hobbes3 os.path.join( os.path.dirname( __file__ ), '..' ) ..に渡されcdたときだけでなく、ファイルシステム全体の上のディレクトリを意味します。
Michael Berkowski

3
@マイケル、おそらく使用する方が良いos.path.join( os.path.dirname ( __file__), os.path.pardir)
mgilson 2012年

回答:


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

テンプレートフォルダーの移動先については、Django 1.4がリリースされたばかりでまだ確認していないため、わかりません。その問題を解決するには、おそらくSEで別の質問をする必要があります。

normpathではなく、を使用してパスをクリーンアップすることもできabspathます。ただし、この状況では、Djangoは相対パスではなく絶対パスを想定しています。

クロスプラットフォームの互換性のためos.pardirに、の代わりにを使用してください'..'


4
使用するのは悪い考え..でしょうか?この回答の投票数が減るのはなぜですか?
hobbes3 2012年

1
なぜ投票数が減っているのかはわかりませんが、私はいつもそれを使っています。の例でも定義されていnormpathます。さらに、シンボリックリンクを適切にトラバースします。
forivall 2012年

1
abspathを使用すると、少しクリーンアップされます。そこにない場合、パス名の実際の文字列はになります/Users/hobbes3/Sites/mysite/mysite/../templates。これは完全に問題ありませんが、少し乱雑です。また、絶対パスを使用するというDjangoの注意事項が確実に守られます。相対パスを使用する別の状況にいる場合は、代わりにnormpathを使用してパスを簡略化する必要があります。
forivall 2012年

2
この質問は、Djangoの新しいバージョンのフォルダー構造の移行に関してたずねられただけなので、おそらく2番目の問題を解決するためにそれを検討する必要があります。
forivall 2012年

1
@Zitraxこれが異なるプラットフォームを知っていますか、それとも将来の安全のためだけに存在しますか?(私は実際には知りos.pardirませんでした、実際にosドキュメントの
最後に到達

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


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

シンボリックリンクがない場合、2つの答えは同じです。


このアプローチに問題はありますか?見栄えが良く、見た目は良いですが、少しハッキリです;)
Gricha

リンクの処理方法は、受け入れられた回答とは少し異なります。それ以外は同じです。
アントニーハッチキンズ2013

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 2018年

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すると、そのように1つ上のディレクトリに移動できます

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.