python NameError:グローバル名 '__file__'が定義されていません


112

このコードをpython 2.7で実行すると、次のエラーが発生します。

Traceback (most recent call last):
File "C:\Python26\Lib\site-packages\pyutilib.subprocess-3.5.4\setup.py", line 30, in <module>
    long_description = read('README.txt'),
  File "C:\Python26\Lib\site-packages\pyutilib.subprocess-3.5.4\setup.py", line 19, in read
    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
NameError: global name '__file__' is not defined

コードは:

import os
from setuptools import setup


def read(*rnames):
    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()


setup(name="pyutilib.subprocess",
    version='3.5.4',
    maintainer='William E. Hart',
    maintainer_email='wehart@sandia.gov',
    url = 'https://software.sandia.gov/svn/public/pyutilib/pyutilib.subprocess',
    license = 'BSD',
    platforms = ["any"],
    description = 'PyUtilib utilites for managing subprocesses.',
    long_description = read('README.txt'),
    classifiers = [
        'Development Status :: 4 - Beta',
        'Intended Audience :: End Users/Desktop',
        'License :: OSI Approved :: BSD License',
        'Natural Language :: English',
        'Operating System :: Microsoft :: Windows',
        'Operating System :: Unix',
        'Programming Language :: Python',
        'Programming Language :: Unix Shell',
        'Topic :: Scientific/Engineering :: Mathematics',
        'Topic :: Software Development :: Libraries :: Python Modules'],
      packages=['pyutilib', 'pyutilib.subprocess', 'pyutilib.subprocess.tests'],
      keywords=['utility'],
      namespace_packages=['pyutilib'],
      install_requires=['pyutilib.common', 'pyutilib.services']
      )

回答:


134

このエラーはos.path.join(os.path.dirname(__file__))、Pythonインタラクティブシェルでこの行を追加したときに発生します。

Python Shellは現在のファイルパスを検出せず、この行を追加した場所に__file__関連してfilepathいます

したがって、この行をos.path.join(os.path.dirname(__file__))に記述してくださいfile.py。そして、それを実行しますpython file.py、それはあなたのファイルパスを取るので機能します。


8
まさに私の経験。しかし、それをシェル内で機能させるにはどうすればよいですか?
s2t2

1
ただしfile.py、スクリプトから実行するには、たとえばスクリプトと同じディレクトリに配置します。したがって、実行する前にこのディレクトリに移動する必要がありますfile.py...それでも、もっと良いものが求められています。
ztyh

EmacsはCc Cpのときにインタラクティブシェルを使用しますか?python-shell。このシェルをファイルを実行している端末のように使用する方法はありますか?シェルを実行するには3つのオプションがあります。CMD DEDICATED SHOWそれらの1つはこれを行いますか?
sinekonata

18

PyInstallerとPy2exeで同じ問題が発生したため、cx-freezeのFAQで解決策を見つけました。

コンソールから、またはアプリケーションとしてスクリプトを使用する場合、以下の関数は「実際のファイルパス」ではなく「実行パス」を提供します。

print(os.getcwd())
print(sys.argv[0])
print(os.path.dirname(os.path.realpath('__file__')))

出典:http :
//cx-freeze.readthedocs.org/en/latest/faq.html

あなたの古い行(最初の質問):

def read(*rnames):
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()

コード行を次のスニペットに置き換えます。

def find_data_file(filename):
    if getattr(sys, 'frozen', False):
        # The application is frozen
        datadir = os.path.dirname(sys.executable)
    else:
        # The application is not frozen
        # Change this bit to match where you store your data files:
        datadir = os.path.dirname(__file__)

    return os.path.join(datadir, filename)

上記のコードを使用すると、アプリケーションをOSのパスに追加でき、アプリがデータ/構成ファイルを見つけられないという問題なく、どこでも実行できます。

Pythonでテスト:

  • 3.3.4
  • 2.7.13

12

次のようにコードを変更してください!わたしにはできる。`

os.path.dirname(os.path.abspath("__file__"))

7
docos.getcwd()よると、あなたは実際にを使用していると思いますが、これは意味がありません。"__file__"
davidlatwe 2018

5
なぜこれには賛成票があるのですか?その多くの人々がこれを取り、それが未処理の例外を取り除いたので、彼らはそれが正しいと思いましたか?これは正しい解決策ではありません。それがしていることは、あなたが文字通り「__file__」という名前のファイルを持っていると言っていて、それが存在
トッド

11

__file__期待どおりに動作しない場合があります。しかし、これまでのところ、私は失敗していません。

import inspect
src_file_path = inspect.getfile(lambda: None)

これは、CのPythonアナログに最も近いもの__FILE__です。

Pythonの動作は__file__Cの動作とは大きく異なり__FILE__ます。Cバージョンは、ソースファイルの元のパスを提供します。これは、エラーを記録し、どのソースファイルにバグがあるかを知るのに役立ちます。

Python __file__は、現在実行中のファイルの名前のみを提供します。これは、ログ出力ではあまり役に立たない場合があります。


2
これは、Pythonが別のアプリケーションに埋め込まれている場合にも機能します
sdaau

私はこのos.path.dirname(os.path.realpath(...))方法よりもこれで運が良かった。
S氏

1
これが一番の答えになるはずです。
183.amir

9

インタラクティブインタープリタを使用していますか?使用できます

sys.argv[0]

あなたは読むべきです:Pythonで現在実行されているファイルのパスを取得するにはどうすればよいですか?


fd = os.path.dirname(os.path.realpath(file))nd印刷する... / .. / folder1 /しかしcwd = os.path.dirname(os.path.realpath(sys.argv [0 ]))>>> print cwd prints ../../
bruceparker

7
これは、現在の作業ディレクトリではなく、シェルを起動したバイナリpythonへのパスを提供します
hobs

それはする必要がありますargv[1]代わりにargv[0]
plustar

9

私はファイルを文字列として扱うことで解決しました。つまり、"__file__"(引用符と一緒に!)__file__

これは私にとってはうまくいきます:

wk_dir = os.path.dirname(os.path.realpath('__file__'))

8
これは確かに機能しますが、なぜか頭がよくありません。"__file__"引用符間での扱いが引用符__file__なしと異なるのはなぜですか?
Gio

5
欠落しているグローバル変数を参照しないためです。代わりに、文字列 ' file 'をパスの一部として扱います。
JoshVarty 2014

42
これは、ファイルが置かれているディレクトリを返すのではなく、現在の作業ディレクトリ(pythonが呼び出される)を返します。-1
Xiangyu

8
の代わりに任意のファイル名を使用できます"__file__"。例えばrealpath('nonexistentfile.whatever')
ホブ、

35
この答えは正しくないので誤解を招くので、実際には削除する必要があります。それが非常に賛成されているという事実はかなり心配です...
Cas

6

コードのどこかで作業ディレクトリを変更していなければ、現在の作業ディレクトリを取得するos.getcwd()だけで同じことが得os.path.dirname(__file__)られます。 os.getcwd()インタラクティブモードでも動作します。

そう os.path.join(os.path.dirname(__file__)) なる os.path.join(os.getcwd())


これは勝者です
Shawn

1
この答えは正しくありませんos.path.dirname(__file__)と同じことを報告しませんos.getcwd()。それはあなたにファイルのディレクトリ名を与えます。それが一致os.getcwd()することが判明した場合、それは単なる偶然です。
トッド

4

Pythonシェルからコマンドを実行している場合は、次のようになります。

>>> __file__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name '__file__' is not defined

pythonコマンドの引数として渡して、ファイルを直接実行する必要があります。

$ python somefile.py

あなたの場合、それは本当に python setup.py install


2

あなたができることは以下を使うことです

import os
if '__file__' in vars():
    wk_dir = os.path.dirname(os.path.realpath('__file__'))
else:
    print('We are running the script interactively')

文字列を使用する'__file__'と、実際の変数が実際に参照されることに注意してください__file__。もちろん、これを自分でテストできます。

このソリューションの追加の利点は、スクリプトを部分的にインタラクティブに(たとえば、テスト/開発するために)実行するときの柔軟性であり、コマンドラインから実行できます。


あなたのメモに関して、'__file__'は有効な変数名であり、あなたのif条件は真になりますが、ファイルの名前であるかのようにos.path.realpath('__file__')扱う偽のパスを返し'__file__'ます。を介して必要なのがその親ディレクトリだけであれば、問題ありませんがos.path.dirname()、これは「ハック」です。@zwep
トッド

また__file__、ソースファイル内から参照すると、それが使用されているファイルのパスが取得されos.getcwd()ます。これはとは異なります。それは常にあなたのwk_dir-または作業ディレクトリではありません。
トッド

2

コマンドラインを介してファイルを実行している場合は、このハックを使用できます

import traceback

def get_this_filename():
    try:
        raise NotImplementedError("No error")
    except Exception as e:
        exc_type, exc_value, exc_traceback = sys.exc_info()
        filename = traceback.extract_tb(exc_traceback)[-1].filename
    return filename

これはUnrealEnginePythonコンソールで私のために働き、 py.exec myfile.py


1

Jupyterノートブックでも同じ問題が発生しました。'os.path.split(os.path.realpath(file))' を使用している間、ノートブックはエラーをスローしていました。

このように私は「ファイル」を使用しました。それは完全に機能しました。


0

私はまったく同じ問題を抱えており、おそらく同じチュートリアルを使用しています。関数定義:

def read(*rnames):
    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()

os.path.dirname(__file__)あなたが必要とするものを返さないので、バグがあります。で置き換えos.path.dirname(__file__)てみてくださいos.path.dirname(os.path.abspath(__file__))

def read(*rnames):
    return open(os.path.join(os.path.dirname(os.path.abspath(__file__)), *rnames)).read()

現在のドキュメントのコードスニペットが機能しないことをアンドリューに投稿したところです。うまくいけば、修正されるでしょう。

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