Pythonで現在のスクリプトの名前を取得する


407

現在実行中のPythonスクリプトの名前を取得しようとしています。

スクリプトが呼び出されましfoo.pyた。スクリプト名を取得するために、次のようなことをしたいと思います。

print Scriptname

回答:


620

を使用__file__して、現在のファイルの名前を取得できます。メインモジュールで使用する場合、これは最初に呼び出されたスクリプトの名前です。

ディレクトリ部分(存在する場合があります)を省略したい場合は、を使用できますos.path.basename(__file__)


15
Python 3.2: " Exception NameError: NameError("global name '__file__' is not defined",)"
sdaau 2013年

20
@sdaau:__file__インタラクティブインタープリターでは定義されていません。意味がないためです。これはインポートの実装によって設定されるため、非標準のインポートメカニズムを使用する場合は、設定が解除されることもあります。
Sven Marnach 2013年

8
少なくともPython 2.7のimport os場合、これを機能させるにはが必要だと思います。これを答えに追加します。
Nick Chammas 14

14
@ cdunn2001:import osimport os.path完全に同等です。
Sven Marnach 14

2
@ sven-marnach:ああ、そうだね。私は何年も間違ってやっています!
cdunn2001

136
import sys
print sys.argv[0]

これはfoo.pyfor python foo.pydir/foo.pyfor python dir/foo.pyなどを出力します。これはの最初の引数pythonです。(py2exeの後はになることに注意してくださいfoo.exe。)


33
@DenisMalinovsky:「機能しない」を定義します。を呼び出すpython linkfile.pyと、linkfile.pyはへのシンボリックリンクでrealfile.pysys.argv[0]はに'linkfile.py'なります。それは確かに私が期待することです。__file__同じです:になりますlinkfile.py。から検索'realfile.py'したい場合は'linkfile.py'、を試してくださいos.path.realpath('linkfile.py')
クリスモーガン

6
+1は(a)少しすっきりしていて、(b)モジュールでも機能します(ファイル変数はモジュールファイルであり、実行されたファイルではありません)。
ロバート

IDLEでも機能するため、この回答は適切です。注として、ファイル名のみを取得するには、os.path.basename(sys.argv [0])と記述できます
Steven Bluen

さらに重要なことに、これはメインファイル内から以外は機能しません。これは使用せず、__file__代わりに使用してください。
Apollysはモニカ

何!!!あなたもこれを試しましたか?まさにその逆です。質問者は、現在実行中のpythonファイルではなく、実行中のpythonスクリプトの名前を尋ねました。エラーが発生したときに、許可された引数とともにスクリプト名を出力するスクリプトがあるとします。これら2つの手法のいずれかを使用して、関数に入れます。ある時点で、関数を外部ライブラリに移動することにしました。実行中のメインスクリプトの名前、または実行中のライブラリファイルの名前を出力しますか?
John Deighan

71

完全を期すために、考えられるさまざまな結果を要約し、それぞれの正確な動作の参照を提供することは価値があると思いました。

  • __file__公式ドキュメントに詳述されているように、現在実行中のファイルです:

    __file__モジュールがファイルからロードされた場合、モジュールのロード元のファイルのパス名です。__file__属性は、次のようなモジュールの特定のタイプのために不足していることができるCの静的インタプリタにリンクされているモジュール。共有ライブラリから動的にロードされる拡張モジュールの場合、これは共有ライブラリファイルのパス名です。

    現在実行中のファイルが相対パスを使用して直接(コマンドラインオプションを指定したインタープリターを介さ__file__ずに)実行されたスクリプトでない限り、Python3.4以降、問題18416に従って、常に絶対パスになり-mます。

  • __main__.__file__(インポートが必要__main__)コマンドラインから呼び出されたスクリプト__file__など、メインモジュールの前述の属性にアクセスするだけです。

  • sys.argv[0](インポートが必要sys)は、コマンドラインから呼び出されたスクリプト名であり、公式ドキュメントに記載されているように、絶対パスの場合があります

    argv[0]スクリプト名です(これは絶対パス名であるかどうかに関係なく、オペレーティングシステムに依存します)。コマンドが-cインタープリターのコマンドラインオプションを使用して実行された場合、argv[0]は文字列に設定されます'-c'。スクリプト名がPythonインタープリターに渡されなかった場合argv[0]、空の文字列になります。

    で述べたように、この質問に別の答えPythonのようなツールを使用して、スタンドアロンの実行可能プログラムに変換したスクリプトpy2exeまたはpyInstallerのは、このアプローチを使用するときに望ましい結果が表示されない場合があります(つまりは、sys.argv[0]実行ファイルの名前ではなく、名前を開催しますその実行可能ファイル内のメインPythonファイルの)。

  • おそらく不規則なインポート操作が原因で、前述のオプションのいずれも機能しないように見える場合は、inspectモジュールが役立つ可能性があります。特に、Pythonスタックフレームなしの実装で実行すると後者が返さinspect.getfile(...)れますinspect.currentframe()が、を呼び出すと機能します。None


シンボリックリンクの処理

現在のスクリプトがシンボリックリンクの場合、上記のすべてが実際のファイルのパスではなくシンボリックリンクのパスを返すos.path.realpath(...)ため、後者を抽出するために呼び出す必要があります。


実際のファイル名を抽出するためのさらなる操作

os.path.basename(...)のように、実際のファイル名を抽出するために上記のいずれかで呼び出すことができos.path.splitext(...)、サフィックスを切り捨てるために実際のファイル名で呼び出すことができますos.path.splitext(os.path.basename(...))

以下からのPython 3.4以降、当たりPEP 428PurePathクラスpathlibモジュールは、上記のいずれかでよくとして使用することができます。具体的にはpathlib.PurePath(...).name、実際のファイル名をpathlib.PurePath(...).stem抽出し、サフィックスなしで実際のファイル名を抽出します。


66

__file__は、このコードが存在するファイルを提供することに注意してください。このファイルはインポートでき、解釈されるメインファイルとは異なります。メインファイルを取得するには、特別な__main__モジュールを使用できます。

import __main__ as main
print(main.__file__)

注意__main__.__file__それがポータブルにするために、上記のようにはPython 2.7でなく3.2での作品は、その輸入などの構文を使用します。


これは多くの場合機能しrPythonますが、R言語のパッケージを使用している場合は機能しません。これは、処理が非常に難しい例外的なケースでなければなりません。
Leonid

実際、rPythonパッケージにはpythonインタープリターが組み込まれています。つまり、Pythonが単独で実行されているときのような「メイン」ファイルはありません(Pythonが埋め込まれているときはいつでも同じ動作が見られます)。__main__はとの間Rで変数を渡す際に使用するために内部的にインポートpythonするため__main__.__file__、他を呼び出す前に設定するのは比較的簡単ですが、この場合の適切な値がどれかわかりません。
Perkins

42

上記の答えは良いです。しかし、上記の結果を使用すると、この方法の方が効率的であることがわかりました。
これにより、実際のスクリプトファイル名がパスではなくなります。

import sys    
import os    
file_name =  os.path.basename(sys.argv[0])

1
私も拡張機能を分割したいので、以下を使用します:os.path.splitext(os.path.basename(sys.argv [0]))[0]
RufusVS

19

最新のPythonバージョン(3.4以降)の場合、Path(__file__).nameより慣用的になるはずです。また、拡張子Path(__file__).stemなしのスクリプト名を提供します.py


NameError:名前「パス」が定義されていません
RufusVS

5
あなたがfrom pathlib import Path最初にすべきです。
Emil Melnikov

「モダン」とはPython 3.xを意味しますか?
einpoklum

1
@einpoklum pathlibはPython 3.4で導入されたため、Python 3.4以降で機能するはずです。
Andrey Semakin


9

注:Python 3以降を使用している場合は、代わりにprint()関数を使用する必要があります

ファイル名がfoo.pyであるとすると、以下のスニペット

import sys
print sys.argv[0][:-3]

または

import sys
print sys.argv[0][::-1][3:][::-1]

ファイル名など、より多くの文字を含む他の拡張子については、 foo.pypy

import sys
print sys.argv[0].split('.')[0]

絶対パスから抽出したい場合

import sys
print sys.argv[0].split('/')[-1].split('.')[0]

出力されます foo


1
sys.argv [0] [:-3]は実行します
kon

よりエレガントな
@konpsych

そこの間には大きな違いだ__file__sys.argv[0]、見stackoverflow.com/questions/5851588/...
Maksym Ganenko


7

通常とは異なるインポート(たとえば、オプションファイル)を実行する場合は、次のことを試してください。

import inspect
print (inspect.getfile(inspect.currentframe()))

これはファイルへの絶対パスを返すことに注意してください。


3

これを試して、拡張子なしの現在のスクリプト名を取得できます。

import os

script_name = os.path.splitext(os.path.basename(__file__))[0]

2

OPが現在のスクリプトファイルの名前を要求したので、

import os
os.path.split(sys.argv[0])[1]

1

これらの答えはすべてすばらしいですが、いくつかの問題があります。

必要なものを定義しましょう-現在のモジュールの名前ではなく、実行されたスクリプトの名前が欲しいので__file__、インポートされたモジュールではなく、実行されたスクリプトで使用された場合にのみ機能します。 sys.argvも疑問です-プログラムがpytestによって呼び出された場合はどうなりますか?またはpydoc runner?またはそれがuwsgiによって呼び出された場合は?

そして-スクリプト名を取得する3つ目の方法があります。答えには出てきません。スタックを調べることができます。

別の問題は、あなた(または他のプログラム)が改ざんしたりsys.argv__main__.__file__それはないかもしれないが、それは存在するかもしれません- 。有効な場合とそうでない場合があります。少なくとも、スクリプト(目的の結果)が存在するかどうかを確認できます。

githubの私のライブラリbitranox / lib_programnameはまさにそれを行います:

  • かどうかを確認__main__存在があります
  • かどうかを確認__main__.__file__存在があります
  • __main__.__file__有効な結果が得られますか(そのスクリプトは存在しますか?)
  • そうでない場合:sys.argvを確認します。
  • sys.argvにpytest、docrunnerなどがありますか?->はいの場合は無視してください
  • ここで有効な結果を得ることができますか?
  • そうでない場合:スタックを検査し、そこから結果を取得する可能性があります
  • スタックも有効な結果を提供しない場合は、例外をスローします。

その方法によって、私の解決策は、これまでと取り組んでいますsetup.py testuwsgipytestpycharm pytestpycharm docrunner (doctest)dreampieeclipse

Dell Hellmanによる「Pythonからプロセスの名前を決定する」からのその問題に関する素晴らしいブログ記事もあります。




弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.