home changes contents help options

134:実行しているスクリプトのパスを求める

__file__ を用いると「スクリプトへの相対パス」を取得できます。 Python 2.3 以前では __file__ が使えないので sys.argv[0]? で代用します。 Python インタプリタへの最初の引数、すなわち「スクリプトへの相対パス」となります。

「スクリプトのあるディレクトリの相対パス」を得るには「スクリプトへのパス」を引数にして os.dirname 関数を呼びます。 「スクリプトと同じディレクトリのファイルへの相対パス」を得るには「スクリプトのあるディレクトリのパス」と「ファイル名」を os.path.join 関数であわせます。

「スクリプト名」だけを得たければ os.basename(__file__) を用います。各「絶対パス」が必要であれば各「相対パス」を引数に os.path.abspath を呼びます。

ちなみに os.getcwd() は「スクリプト実行時のカレントディレクトリ」であり、必ずしも「スクリプトのあるディレクトリのパス」と一致しません。「スクリプトのあるディレクトリのパス」は、os.path.abspath(os.path.dirname(__file__))となります。

C:\test ディレクトリの中に python_recipe ディレクトリを作り、その中に getcomposition.py と input.txt を置き、 C:\test ディレクトリからスクリプト getcomposition.py を呼び出すと次のようになります。

  スクリプト getcomposition.py
  import os
  import sys

  print __file__    # スクリプトへの相対パス
  print sys.argv[0] # スクリプトへの相対パス
  print
  print os.path.dirname(__file__) # スクリプトのあるディレクトリへの相対パス
  print

  txt = os.path.join(os.path.dirname(__file__), 'input.txt') # スクリプトと同じディレクトリのファイル input.txt のパス
  print txt
  f = open(txt,'r') # ファイル input.txt を開いて確認
  for line in f:
      print line,
  print

  print os.path.basename(__file__) # スクリプト名
  print os.path.abspath(__file__)  # スクリプトの絶対パス
  print os.path.abspath(os.path.dirname(__file__))  # スクリプトあるディレクトリの絶対パス
  print os.getcwd()                # 実行時カレントディレクトリの絶対パス

  実行
  C:\test> python python_recipe\getcompositon.py

  実行結果
  python_recipe\getcompositon.py
  python_recipe\getcompositon.py

  python_recipe

  python_recipe\input.txt
  1,apple,すっぱい
  2,orange,すっぱい
  3,melon,甘い

  getcompositon.py
  C:\test\python_recipe\getcomposition.py
  C:\test\python_recipe
  C:\test

直接は関係ありませんが、 os.abspath はディレクトリの区切り文字を実行時環境に合わせます。たとえば Windows にて os.abspath("home/seko") を呼ぶとスラッシュはバックスラッシュに置き換わります。

  >>> os.getcwd()
  'C:\\Documents and Settings\\seko'
  >>> path='home/seko'
  >>> os.path.abspath(path)
  'C:\\Documents and Settings\\seko\\home\\seko'

Windows 上でスクリプトを python getcomposition.py として呼んだときと getcomposition.py と関連付けを利用して呼んだときでは __file__ や 'sys.argv[0]?' に入る値に違いがあります。関連付けを利用するとスクリプトの「絶対パス」が入ります。