誰かがクロスプラットフォームの方法でPythonのパスの親ディレクトリを取得する方法を教えてもらえますか?例えば
C:\Program Files ---> C:\
そして
C:\ ---> C:\
ディレクトリに親ディレクトリがない場合は、ディレクトリ自体を返します。質問は単純に思えるかもしれませんが、Googleで詳しく調べることはできませんでした。
誰かがクロスプラットフォームの方法でPythonのパスの親ディレクトリを取得する方法を教えてもらえますか?例えば
C:\Program Files ---> C:\
そして
C:\ ---> C:\
ディレクトリに親ディレクトリがない場合は、ディレクトリ自体を返します。質問は単純に思えるかもしれませんが、Googleで詳しく調べることはできませんでした。
回答:
pathlib
モジュールを使用します。
from pathlib import Path
path = Path("/here/your/path/file.txt")
print(path.parent)
これを試して:
import os.path
print os.path.abspath(os.path.join(yourpath, os.pardir))
どこyourpath
あなたが親をしたいパスです。
os.pardir
、ではありませんos.path.pardir
。
os.pardir
とos.path.pardir
(それらが同一である)、実際に正しいです。
os.path.dirname
パスに末尾のスラッシュが含まれているかどうかによって、残念ながら異なる結果が得られます。信頼できる結果が必要な場合は、os.path.join
上記の方法を使用する必要があります。
使用os.path.dirname
:
>>> os.path.dirname(r'C:\Program Files')
'C:\\'
>>> os.path.dirname('C:\\')
'C:\\'
>>>
警告:os.path.dirname()
末尾のスラッシュがパスに含まれているかどうかによって、異なる結果が得られます。これは、必要なセマンティクスである場合とそうでない場合があります。Cf. を使用した@kenderの回答os.path.join(yourpath, os.pardir)
。
os.path.dirname(r'C:\Program Files')
何?Pythonはファイル 'Program Files'があるディレクトリを提供しているだけです。さらに、それは存在する必要さえありません、見よ:os.path.dirname(r'c:\i\like\to\eat\pie')
出力'c:\\i\\like\\to\\eat'
from pathlib import Path
Path('C:\Program Files').parent
# Returns a Pathlib object
import os.path
os.path.dirname('C:\Program Files')
# Returns a string
次の場合は、従来の方法を使用します。
Pathlibオブジェクトを使用する場合、既存のコードがエラーを生成することを心配しています。(Pathlibオブジェクトは文字列と連結できないため。)
Pythonのバージョンが3.4未満です。
文字列が必要で、文字列を受け取りました。たとえば、ファイルパスを表す文字列があり、JSON文字列に配置できるように親ディレクトリを取得するとします。Pathlibオブジェクトに変換し、そのために再び戻るのは、ばかげたことでしょう。
上記のいずれにも該当しない場合は、Pathlibを使用してください。
Pathlibが何であるかわからない場合、Pathlibモジュールは、ファイルの操作をさらに簡単にする素晴らしいモジュールです。ファイルで機能する組み込みのPythonモジュールのすべてではないにしても、ほとんどがPathlibオブジェクトと文字列の両方を受け入れます。以下に、Pathlibのドキュメントから抜粋して、Pathlibを使用して実行できる優れた機能のいくつかを紹介します。
ディレクトリツリー内を移動する:
>>> p = Path('/etc')
>>> q = p / 'init.d' / 'reboot'
>>> q
PosixPath('/etc/init.d/reboot')
>>> q.resolve()
PosixPath('/etc/rc.d/init.d/halt')
パスプロパティのクエリ:
>>> q.exists()
True
>>> q.is_dir()
False
pip install pathlib2
、バックポートを使用してください。
os.sep
!
import os
p = os.path.abspath('..')
C:\Program Files
---> C:\\\
C:\
---> C:\\\
os.path.abspath(r'E:\O3M_Tests_Embedded\branches\sw_test_level_gp\test_scripts\..\..')
:E:\\O3M_Tests_Embedded\\branches
/
。
@kenderの代替ソリューション
import os
os.path.dirname(os.path.normpath(yourpath))
どこyourpath
あなたが親をしたいパスです。
しかし、このソリューションはyourpath
、が空の文字列またはドットである場合を処理しないため、完全ではありません。
この他のソリューションは、このコーナーケースをよりうまく処理します:
import os
os.path.normpath(os.path.join(yourpath, os.pardir))
ここで、見つけることができるすべてのケースの出力(入力パスは相対です):
os.path.dirname(os.path.normpath('a/b/')) => 'a'
os.path.normpath(os.path.join('a/b/', os.pardir)) => 'a'
os.path.dirname(os.path.normpath('a/b')) => 'a'
os.path.normpath(os.path.join('a/b', os.pardir)) => 'a'
os.path.dirname(os.path.normpath('a/')) => ''
os.path.normpath(os.path.join('a/', os.pardir)) => '.'
os.path.dirname(os.path.normpath('a')) => ''
os.path.normpath(os.path.join('a', os.pardir)) => '.'
os.path.dirname(os.path.normpath('.')) => ''
os.path.normpath(os.path.join('.', os.pardir)) => '..'
os.path.dirname(os.path.normpath('')) => ''
os.path.normpath(os.path.join('', os.pardir)) => '..'
os.path.dirname(os.path.normpath('..')) => ''
os.path.normpath(os.path.join('..', os.pardir)) => '../..'
入力パスは絶対パスです(Linuxパス):
os.path.dirname(os.path.normpath('/a/b')) => '/a'
os.path.normpath(os.path.join('/a/b', os.pardir)) => '/a'
os.path.dirname(os.path.normpath('/a')) => '/'
os.path.normpath(os.path.join('/a', os.pardir)) => '/'
os.path.dirname(os.path.normpath('/')) => '/'
os.path.normpath(os.path.join('/', os.pardir)) => '/'
os.path.split(os.path.abspath(mydir))[0]
os.path.split(os.path.abspath("this/is/a/dir/"))[0]
戻ります'/home/daniel/this/is/a'
。現在のところ、そこで実行するWindowsボックスを実行していません。あなたが報告する行動をどのような設定で観察しましたか?
parentdir = os.path.split(os.path.apspath(dir[:-1]))[0]
。これ-私は確信しています-スラッシュが最後にある場合、それは削除されるので機能します スラッシュがない場合でも、前のスラッシュのため、これは(パスの最後の部分が1文字しかない場合でも)機能します。もちろん、これはパスが適切であり、/a//b/c///d////
(UNIXではこれはまだ有効です)のようなことを言っていないことを前提としています。ほとんどの場合、特に何かos.path.abspath
他のos.path
機能を実行するときに(適切)です。
os.path.split("a/b//c/d///")
たとえばcd //////dev////// is equivalent to
cd / dev / `やcd /dev
;のようなものがある場合は機能しません。これらはすべてLinuxで有効です。私はこれを思いついたばかりですが、それは便利かもしれません:os.path.split(path[:tuple(ind for ind, char in enumerate(path) if char != "/" and char != "\\")[-1]])[0]
。(これは基本的に最後の非スラッシュを検索し、その文字までのパスの部分文字列を取得します。)私path = "/a//b///c///d////"
は前述のステートメントを使用して実行し、を取得しました'/a//b///c'
。
os.path.abspath(os.path.join(somepath, '..'))
観察する:
import posixpath
import ntpath
print ntpath.abspath(ntpath.join('C:\\', '..'))
print ntpath.abspath(ntpath.join('C:\\foo', '..'))
print posixpath.abspath(posixpath.join('/', '..'))
print posixpath.abspath(posixpath.join('/home', '..'))
import os
print"------------------------------------------------------------"
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
print("example 1: "+SITE_ROOT)
PARENT_ROOT=os.path.abspath(os.path.join(SITE_ROOT, os.pardir))
print("example 2: "+PARENT_ROOT)
GRANDPAPA_ROOT=os.path.abspath(os.path.join(PARENT_ROOT, os.pardir))
print("example 3: "+GRANDPAPA_ROOT)
print "------------------------------------------------------------"
引数として提供されるファイルの直接の親であり、そのファイルへの絶対パスではないフォルダーの名前のみが必要な場合:
os.path.split(os.path.dirname(currentDir))[1]
つまり、currentDir
値/home/user/path/to/myfile/file.ext
上記のコマンドは次を返します:
myfile
>>> import os
>>> os.path.basename(os.path.dirname(<your_path>))
たとえば、Ubuntuの場合:
>>> my_path = '/home/user/documents'
>>> os.path.basename(os.path.dirname(my_path))
# Output: 'user'
たとえば、Windowsの場合:
>>> my_path = 'C:\WINDOWS\system32'
>>> os.path.basename(os.path.dirname(my_path))
# Output: 'WINDOWS'
Python 2.7で両方の例を試しました
import os.path
os.path.abspath(os.pardir)
Tungの答えに何かを追加するだけです(rstrip('/')
UNIXボックスを使用している場合は、これを使用して安全性を高める必要があります)。
>>> input = "../data/replies/"
>>> os.path.dirname(input.rstrip('/'))
'../data'
>>> input = "../data/replies"
>>> os.path.dirname(input.rstrip('/'))
'../data'
ただし、を使用しない場合rstrip('/')
、入力が
>>> input = "../data/replies/"
出力します、
>>> os.path.dirname(input)
'../data/replies'
これはあなたが両方をしたいようで、探しているものはおそらくない"../data/replies/"
と"../data/replies"
同じように動作します。
print os.path.abspath(os.path.join(os.getcwd(), os.path.pardir))
これを使用して、pyファイルの現在の場所の親ディレクトリを取得できます。
親ディレクトリのパスを取得し、新しいディレクトリ(名前new_dir
)を作成します
os.path.abspath('..')
os.pardir
import os
print os.makedirs(os.path.join(os.path.dirname(__file__), os.pardir, 'new_dir'))
import os
print os.makedirs(os.path.join(os.path.dirname(__file__), os.path.abspath('..'), 'new_dir'))
os.path.abspath('D:\Dir1\Dir2\..')
>>> 'D:\Dir1'
だから..
助け
上記の回答は、1つまたは2つのディレクトリレベルを上げるのに完全に適していますが、ディレクトリツリーを多数のレベル(たとえば、5または10)トラバースする必要がある場合は、少し面倒になることがあります。これは、リスト結合することにより簡潔に行うことができますN
os.pardir
sでos.path.join
。例:
import os
# Create list of ".." times 5
upup = [os.pardir]*5
# Extract list as arguments of join()
go_upup = os.path.join(*upup)
# Get abspath for current file
up_dir = os.path.abspath(os.path.join(__file__, go_upup))
os.path.dirname
この機能は、次のように、あるa+=5-4
以上回旋ですa+=1
。質問は親ディレクトリのみを要求しました。存在するかどうか、またはシンボリックリンクが邪魔になると想定した真の親ディレクトリは要求しませんでした。