1. ホーム
  2. パイソン

[解決済み】Pythonで現在実行されているファイルのパスを取得する方法は?

2022-04-09 08:30:37

質問

これは初心者の質問のように見えるかもしれませんが、そうではありません。一般的なアプローチでも、すべてのケースでうまくいくとは限りません。

sys.argv[0]です。

を使うということです。 path = os.path.abspath(os.path.dirname(sys.argv[0])) しかし、これは別のディレクトリにある別のPythonスクリプトから実行している場合はうまくいきませんし、これは実際に起こりうることです。

__file__

これは path = os.path.abspath(os.path.dirname(__file__)) しかし、これではうまくいかないことがわかりました。

  • py2exe には __file__ 属性がありますが 回避策
  • から実行すると IDLE execute() はありません。 __file__ 属性
  • Mac OS X v10.6 (Snow Leopard)を取得しました。 NameError: global name '__file__' is not defined

関連する質問で、回答が未完成のもの

を探しています。 汎用ソリューション 上記のすべてのユースケースで動作するものです。

更新情報

以下はテストケースの結果です。

の出力 python a.py (Windowsの場合)

a.py: __file__= a.py
a.py: os.getcwd()= C:\zzz

b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:\zzz

a.py

#! /usr/bin/env python
import os, sys

print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print

execfile("subdir/b.py")

ファイル サブディレクトリ/b.py

#! /usr/bin/env python
import os, sys

print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print

ツリー

C:.
|   a.py
\---subdir
        b.py

解決方法は?

実行されているメインスクリプトの場所を直接特定することはできません。 結局のところ、スクリプトはファイルから全く来ていないこともある。 例えば、対話型インタプリタから来る場合もあるし、メモリにのみ格納された動的に生成されたコードから来る場合もある。

しかし、モジュールは常にファイルからロードされるため、モジュールの場所を確実に特定することができます。 次のようなコードでモジュールを作成し、メインスクリプトと同じディレクトリに置くと、メインスクリプトはそのモジュールをインポートし、それを使って自分自身の位置を特定することができるのです。

some_path/module_locator.py:

def we_are_frozen():
    # All of the modules are built-in to the interpreter, e.g., by py2exe
    return hasattr(sys, "frozen")

def module_path():
    encoding = sys.getfilesystemencoding()
    if we_are_frozen():
        return os.path.dirname(unicode(sys.executable, encoding))
    return os.path.dirname(unicode(__file__, encoding))

some_path/main.py:

import module_locator
my_path = module_locator.module_path()

複数のメインスクリプトが異なるディレクトリにある場合、module_locator のコピーが複数必要な場合があります。

もちろん、メインスクリプトが他のツールによってロードされ、スクリプトと同じ場所にあるモジュールをインポートできない場合は、運が悪いとしか言いようがありません。 そのような場合、あなたが求める情報はプログラムのどこにも存在しないのです。 最善の策は、ツールの作者にバグを報告することでしょう。