理解できません__file__。私が理解したこと__file__から、モジュールのロード元の絶対パスを返します。
これを生成するのに問題があります。returnsから実行されるabc.pywith oneステートメントがあります。返品から実行中。理由は何ですか?print __file__/d/projects/ python abc.pyabc.py/d/projects/abc.py
理解できません__file__。私が理解したこと__file__から、モジュールのロード元の絶対パスを返します。
これを生成するのに問題があります。returnsから実行されるabc.pywith oneステートメントがあります。返品から実行中。理由は何ですか?print __file__/d/projects/ python abc.pyabc.py/d/projects/abc.py
回答:
ドキュメントから:
__file__モジュールがファイルからロードされた場合、モジュールのロード元のファイルのパス名です。この__file__属性は、インタープリターに静的にリンクされているCモジュールには存在しません。共有ライブラリから動的にロードされる拡張モジュールの場合、これは共有ライブラリファイルのパス名です。
質問へのコメントで@kindallによってリンクされたメーリングリストのスレッドから:
私はこの特定の例を再現しようとしませんでしたが、その理由は、すべてのインポートでgetpwd()を呼び出す必要がないことや、現在のディレクトリをキャッシュするためのある種のインプロセス変数を必要としないことです。(getpwd()は比較的低速で、完全に失敗することがあります。キャッシュしようとすると、間違いが発生する危険があります。)
代わりに、sys.pathの要素をウォークスルーして絶対パスに変換するsite.pyのコードを実行します。ただし、このコードは ''がsys.pathの前に挿入される前に実行されるため、sys.pathの初期値は ''です。
これ以降sys.pathは、含めないことを検討してください''。
そのためsys.path、モジュールが含まれている部分の外側にいる場合は、絶対パスを取得します。sys.pathモジュールが含まれている部分の中にいる場合は、相対パスを取得します。
現在のディレクトリにモジュールをロードし、現在のディレクトリがでsys.path、あなたは絶対パスを取得します。
現在のディレクトリにモジュールをロードし、現在のディレクトリがにsys.pathある場合は、相対パスが取得されます。
sys.path、あなたは絶対パスを取得します。現在のディレクトリにモジュールをロードし、現在のディレクトリがにsys.pathある場合は、相対パスが取得されます。
sys.pathは含まれていません''。
__file__相対パスを使用してスクリプトを直接実行する場合を除いて、Python 3.4以降は絶対です。
モジュールの
__file__属性(および関連する値)には、デフォルトで常に絶対パスが含まれるようになりました。ただし__main__.__file__、相対パスを使用してスクリプトが直接実行された場合は例外です。(bpo-18416でBrett Cannonによって寄贈されました。)
ただし、シンボリックリンクが解決されるかどうかは不明です。
相対パスを渡す例:
$ python script.py
Python 3.4.0 (default, Apr 11 2014, 13:05:11) [GCC 4.8.2] on linux)には当てはまりません。そして、私の裁判ではシンボリックリンクは解決されません。
os.path.realpath(__file__)シンボリックリンクを解決する正しい方法はありますか?
後半の簡単な例:
from os import path, getcwd, chdir
def print_my_path():
print('cwd: {}'.format(getcwd()))
print('__file__:{}'.format(__file__))
print('abspath: {}'.format(path.abspath(__file__)))
print_my_path()
chdir('..')
print_my_path()
Python-2。*では、2番目の呼び出しpath.abspath(__file__)は現在のディレクトリに基づいてを誤って決定します。
cwd: C:\codes\py
__file__:cwd_mayhem.py
abspath: C:\codes\py\cwd_mayhem.py
cwd: C:\codes
__file__:cwd_mayhem.py
abspath: C:\codes\cwd_mayhem.py
@techtonikで述べられているように、Python 3.4以降で__file__は絶対パスを返すため、これは正常に動作します。
__main__モジュール、__file__ できる相対パスです。
@kindallによって提供されるGuidoメールの助けを借りて、標準のインポートプロセスをの各メンバーでモジュールを見つけようとするものとして理解し、sys.pathこのルックアップの結果としてファイルすることができます(詳細はPyMOTWモジュールとインポートを参照してください)。したがって、モジュールがsys.path結果の絶対パスに配置されている場合は絶対ですが、相対パスに配置されている場合sys.path、結果のいる場合は相対です。
今、site.pyスタートアップファイルはにのみ、絶対パスを提供するの面倒をsys.path初期を除いて、''ので、あなたは(そのパス接頭辞の前に、絶対的にも作られていますPYTHONPATHを設定するよりも、他の手段でそれを変更しない場合sys.path)、あなたは常に絶対を取得しますパスが、モジュールが現在のディレクトリを介してアクセスされる場合。
面白い方法でsys.pathをだますと、何でも取得できます。
例として、コードを含むサンプルモジュールfoo.pyがある/tmp/とします。
import sys
print(sys.path)
print (__file__)
/ tmpに移動すると、次のようになります。
>>> import foo
['', '/tmp', '/usr/lib/python3.3', ...]
./foo.py
にいるとき、/home/userあなたを追加/tmpするとPYTHONPATH次のようになります:
>>> import foo
['', '/tmp', '/usr/lib/python3.3', ...]
/tmp/foo.py
を追加../../tmpしても正規化され、結果は同じになります。
しかし、使用PYTHONPATHする代わりに、いくつかの面白いパスを直接使用すると、原因と同じくらい面白い結果が得られます。
>>> import sys
>>> sys.path.append('../../tmp')
>>> import foo
['', '/usr/lib/python3.3', .... , '../../tmp']
../../tmp/foo.py
Guidoは上記のスレッドで、Pythonが絶対パスのすべてのエントリを変換しようとしない理由を説明しています。
すべてのインポートでgetpwd()を呼び出す必要はありません.... getpwd()は比較的低速であり、完全に失敗することがあります。
したがって、パスはそのまま使用されます。