回答:
を使用__file__
して、現在のファイルの名前を取得できます。メインモジュールで使用する場合、これは最初に呼び出されたスクリプトの名前です。
ディレクトリ部分(存在する場合があります)を省略したい場合は、を使用できますos.path.basename(__file__)
。
__file__
インタラクティブインタープリターでは定義されていません。意味がないためです。これはインポートの実装によって設定されるため、非標準のインポートメカニズムを使用する場合は、設定が解除されることもあります。
import os
場合、これを機能させるにはが必要だと思います。これを答えに追加します。
import os
とimport os.path
完全に同等です。
import sys
print sys.argv[0]
これはfoo.py
for python foo.py
、dir/foo.py
for python dir/foo.py
などを出力します。これはの最初の引数python
です。(py2exeの後はになることに注意してくださいfoo.exe
。)
python linkfile.py
と、linkfile.py
はへのシンボリックリンクでrealfile.py
、sys.argv[0]
はに'linkfile.py'
なります。それは確かに私が期待することです。__file__
同じです:になりますlinkfile.py
。から検索'realfile.py'
したい場合は'linkfile.py'
、を試してくださいos.path.realpath('linkfile.py')
。
__file__
代わりに使用してください。
完全を期すために、考えられるさまざまな結果を要約し、それぞれの正確な動作の参照を提供することは価値があると思いました。
__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 428、PurePath
クラスのpathlib
モジュールは、上記のいずれかでよくとして使用することができます。具体的にはpathlib.PurePath(...).name
、実際のファイル名をpathlib.PurePath(...).stem
抽出し、サフィックスなしで実際のファイル名を抽出します。
__file__
は、このコードが存在するファイルを提供することに注意してください。このファイルはインポートでき、解釈されるメインファイルとは異なります。メインファイルを取得するには、特別な__main__モジュールを使用できます。
import __main__ as main
print(main.__file__)
注意__main__.__file__
それがポータブルにするために、上記のようにはPython 2.7でなく3.2での作品は、その輸入などの構文を使用します。
rPython
ますが、R
言語のパッケージを使用している場合は機能しません。これは、処理が非常に難しい例外的なケースでなければなりません。
__main__
はとの間R
で変数を渡す際に使用するために内部的にインポートpython
するため__main__.__file__
、他を呼び出す前に設定するのは比較的簡単ですが、この場合の適切な値がどれかわかりません。
最新のPythonバージョン(3.4以降)の場合、Path(__file__).name
より慣用的になるはずです。また、拡張子Path(__file__).stem
なしのスクリプト名を提供します.py
。
from pathlib import Path
最初にすべきです。
pathlib
はPython 3.4で導入されたため、Python 3.4以降で機能するはずです。
ファイル名が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
sysの最初の引数は現在のファイル名になるので、これは機能します
import sys
print sys.argv[0] # will print the file name
通常とは異なるインポート(たとえば、オプションファイル)を実行する場合は、次のことを試してください。
import inspect
print (inspect.getfile(inspect.currentframe()))
これはファイルへの絶対パスを返すことに注意してください。
これらの答えはすべてすばらしいですが、いくつかの問題があります。
必要なものを定義しましょう-現在のモジュールの名前ではなく、実行されたスクリプトの名前が欲しいので__file__
、インポートされたモジュールではなく、実行されたスクリプトで使用された場合にのみ機能します。
sys.argv
も疑問です-プログラムがpytestによって呼び出された場合はどうなりますか?またはpydoc runner?またはそれがuwsgiによって呼び出された場合は?
そして-スクリプト名を取得する3つ目の方法があります。答えには出てきません。スタックを調べることができます。
別の問題は、あなた(または他のプログラム)が改ざんしたりsys.argv
、__main__.__file__
それはないかもしれないが、それは存在するかもしれません- 。有効な場合とそうでない場合があります。少なくとも、スクリプト(目的の結果)が存在するかどうかを確認できます。
githubの私のライブラリbitranox / lib_programnameはまさにそれを行います:
__main__
存在があります__main__.__file__
存在があります__main__.__file__
有効な結果が得られますか(そのスクリプトは存在しますか?)その方法によって、私の解決策は、これまでと取り組んでいますsetup.py test
、uwsgi
、pytest
、pycharm pytest
、pycharm docrunner (doctest)
、dreampie
、eclipse
Dell Hellmanによる「Pythonからプロセスの名前を決定する」からのその問題に関する素晴らしいブログ記事もあります。
os.path.abspath(__file__)
絶対パスをrelpath()
提供します(利用可能)。
sys.argv[-1]
相対パスを提供します。
Python 3.5以降では、次のように簡単に実行できます。
from pathlib import Path
Path(__file__).stem
詳細はこちら: https //docs.python.org/3.5/library/pathlib.html#pathlib.PurePath.stem
たとえば、ユーザーディレクトリの下に次の名前のファイルがありますtest.py
。
from pathlib import Path
print(Path(__file__).stem)
print(__file__)
この出力を実行する:
>>> python3.6 test.py
test
test.py
Exception NameError: NameError("global name '__file__' is not defined",)
"