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']
      )

Answers:


134

当您将此行添加os.path.join(os.path.dirname(__file__))到python交互式shell中时,会出现此错误。

Python Shell不会检测到其中的当前文件路径,__file__并且与filepath您添加此行的位置有关

所以,你应该写这条线os.path.join(os.path.dirname(__file__))file.py。然后运行python file.py,它起作用,因为它需要您的文件路径。


8
正是我的经验。但是如何使其在外壳中工作?
s2t2 '18年

1
但是file.py要从脚本运行,您可以将其放置在与脚本相同的目录中。因此,您需要在运行之前移至该目录file.py。因此,仍在寻求更好的方法。
ztyh

因此,当您Cc Cp时,Emacs使用交互式外壳程序吗?python-shell。有没有办法使用此shell,就像它是运行文件的终端一样?运行shell有3个选项:CMD专用显示其中之一可以执行此操作吗?
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
os.getcwd()根据doc,我认为您实际上正在使用,而"__file__"毫无意义。
davidlatwe

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 print it print ... / .. / folder1 /但是cwd = os.path.dirname(os.path.realpath(sys.argv [0 ]))>>> print cwd prints ../../
bruceparker 2015年

7
这将提供启动外壳程序的二进制python的路径,而不是当前的工作目录
滚刀

应该argv[1]代替argv[0]
plustar

9

我通过将文件视为字符串来解决它,即放在"__file__"(加上引号!)而不是__file__

这对我来说很好:

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

8
这确实有效,但是我无法理解为什么。为什么"__file__"引号之间的对待与__file__不引号之间的对待不同?
2014年

5
因为它没有引用丢失的全局变量。相反,它将字符串' file '视为路径的一部分。
JoshVarty 2014年

42
这不返回所在目录文件的位置,但只是返回当前工作目录(其中蟒蛇被调用)。-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 shell运行命令,则将获得以下信息:

>>> __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条件为true,但os.path.realpath('__file__')将返回伪路径'__file__',就好像它是文件名一样。如果只需要通过为其父目录os.path.dirname(),就可以了-但这是“黑客”。@zwep
托德

另外,__file__从源文件中进行引用也将获得其所用文件的路径-这与并不相同os.getcwd()。它并不总是您的wk_dir-或工作目录。
托德

2

如果您通过命令行执行文件,则可以使用此hack

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()

我刚刚发布了Andrew消息,当前文档中的代码段不起作用,希望它会得到纠正。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.