os.path.join() による絶対パスの構築

Pythonで絶対パスを構築したいのですが、同時にpath-separatorのようなものをかなり意識しないようにします。

edit0: 例えば、ファイルシステムのルートに /etc/init.d (w32 では C:\etcinit.d) というディレクトリがあって、 etcinit.d (w32 では C: というディスクIDも必要かも) からだけ構成したいのですが、どうしたらいいですか?

パス区切り文字を気にする必要がないように、 os.join.path() は明らかに選択されたツールです。しかし、この方法では 相対的な パスしか作れないようです。

 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() を使用すると、相対パスから絶対パスへの変換のみが試されます。 e.g. 作業ディレクトリ /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: the question really boils down to: /etc/init.d のリーディングスラッシュはこのパスを絶対パスにするので、このリーディングスラッシュをプログラム的に構築する方法はありますか? (先頭のスラッシュが絶対パスを示しているという仮定はしたくないのです)

ソリューション

そこで、私が思いついた解決策は、与えられたファイルを辿ってファイルシステムのルートを構築することです。

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')
解説 (5)

そのため、実行中のOSのチェックを行うことができる をチェックすることができます。

でチェックできます。

>>> sys.platform
'win32'

リナックス上

>>> sys.platform
'linux2'

では

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

'linux2' はすべてのLinuxディストロをカバーしているわけではないことに注意してください。

解説 (10)

os.path.splitdriveを使ってドライブ/ファイルシステムの名前を取得し、これをfoo` 文字列と結合することができます。

http://docs.python.org/2/library/os.path.html#os.path.splitdrive

のようなものです (未検証!)。

(drive, tail) = os.path.splitdrive(os.getcwd())
os.path.join(drive, 'foo')

のようにすればよいでしょう。

解説 (1)