web-dev-qa-db-ja.com

os.path.join()を使用した絶対パスの構築

Pythonで絶対パスを構築したいのですが、同時にパスセパレーターのようなものをかなり忘れています。

edit0:たとえば、ファイルシステム/etc/init.d(またはw32ではC:\etc\init.d)のルートにディレクトリがあり、要素etcおよびinit.d(w32では、おそらくC:のようなディスクID)

パス区切り文字を心配する必要がないため、os.join.path()が明らかに最適なツールです。しかし、これはrelativeパスのみを作成するようです:

 print "MYPATH:", os.path.join('etc', 'init.d')
 MYPATH: etc/init.d

ダミーの最初の要素(''など)を追加しても何の助けにもなりません。

 print "MYPATH:", os.path.join('', 'etc', 'init.d')
 MYPATH: etc/init.d

最初の要素を絶対にすることは明らかに役立ちますが、この種のos.path.join()を使用するという考えは無効になります

 print "MYPATH:", os.path.join('/etc', 'init.d')
 MYPATH: /etc/init.d

edit1:os.path.abspath()を使用すると、相対パスのみが絶対パスに変換されます。例えば作業ディレクトリ/home/fooで次を実行することを検討してください。

 print "MYPATH:", os.path.abspath(os.path.join('etc', 'init.d'))
 MYPATH: /home/foo/etc/init.d

それでは、パスを「ルート化」する標準的なクロスプラットフォームの方法は何ですか?

 root = ??? # <--
 print "MYPATH:", os.path.join(root, 'etc', 'init.d')
 MYPATH: /etc/init.d

edit2:質問は本当に要約されます:/etc/init.dの先頭のスラッシュはこのパスを絶対パスにするので、この先頭のスラッシュをプログラムで構築する方法はありますか? (先頭のスラッシュが絶対パスを示していると仮定したくない)

41
umläute

だから私が思いついた解決策は、与えられたファイルをルートにしてファイルシステムのルートを構築することです:

def getRoot(file=None):
  if file is None:
      file='.'
  me=os.path.abspath(file)
  drive,path=os.path.splitdrive(me)
  while 1:
    path,folder=os.path.split(path)
    if not folder:
       break
  return drive+path

 os.path.join(getRoot(), 'etc', 'init.d')
2
umläute

ルートとして_os.sep_を使用するとうまくいきました:

_path.join(os.sep, 'python', 'bin')
_

Linux:_/python/bin_

Windows:_\python\bin_

path.abspath()をミックスに追加すると、Windowsでもドライブ文字が提供され、Linuxと互換性があります。

_path.abspath(path.join(os.sep, 'python', 'bin'))
_

Linux:_/python/bin_

Windows:_C:\python\bin_

58
girardc79

os.path.normpathを使用できると思います。 Windowsで取得できるものは次のとおりです。

>>> os.path.normpath("/etc/init.d")
'\\etc\\init.d'

ドライブプレフィックスを正しく処理するかどうかは正確にはわかりませんが、これを省略することは、「現在使用中のドライブを使用し続ける」などのことを意味すると思います。 Windowsに精通している人が明らかになるかもしれませんか?

4
Jack O'Connor

したがって、sys.platfromでosの実行を確認できます。

窓の上

>>> sys.platform
'win32'

linuxで

>>> sys.platform
'linux2'

それから

if sys.platform == 'win32':
    ROOT = os.path.splitdrive(os.path.abspath('.'))[0]
Elif sys.platform == 'linux2':
    ROOT = os.sep

「linux2」はすべてのLinuxディストリビューションをカバーするわけではないことに注意してください

1
Ansuman Bebarta