python 如何在 py2exe 中获取可执行文件的当前目录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2292703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-04 00:17:25  来源:igfitidea点击:

how can i get the executable's current directory in py2exe?

pythonpy2exe

提问by Chris Lamberson

I use this bit of code in my script to pinpoint, in a cross-platform way, where exactly it's being run from:

我在我的脚本中使用这段代码以跨平台的方式精确定位它的运行位置:

SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))

Pretty simple. I then go on to use SCRIPT_ROOTin other areas of my script to make sure everything is properly relative. My problem occurs when I run it through py2exe, because the generated executable doesn't set __file__, therefore my script breaks. Does anyone know how to fix or work around this?

很简单。然后我继续在SCRIPT_ROOT我的脚本的其他区域使用,以确保一切都是正确的。当我通过 py2exe 运行它时,我的问题出现了,因为生成的可执行文件没有设置__file__,因此我的脚本中断了。有谁知道如何解决或解决这个问题?

回答by John Machin

Here is the py2exe documentation referenceand here are the relevant items:

这是py2exe 文档参考,这里是相关项目:

  • sys.executableis set to the full pathname of the exe-file.
  • The first item in sys.argvis the full pathname of the executable, the rest are the command line arguments.
  • sys.frozenonly exists in the executable. It is set to "console_exe" for a console executable, to "windows_exe" for a console-less gui executable, and to "dll" for a inprocess dll server.
  • __file__is not defined (you might want to use sys.argv[0] instead)
  • sys.executable设置为 exe 文件的完整路径名。
  • 中的第一项sys.argv是可执行文件的完整路径名,其余的是命令行参数。
  • sys.frozen只存在于可执行文件中。对于控制台可执行文件,它被设置为“console_exe”,对于无控制台的 gui 可执行文件,它被设置为“windows_exe”,对于进程内的 dll 服务器,它被设置为“dll”。
  • __file__未定义(您可能想使用 sys.argv[0] 代替)

It is not apparent from those docs whether "the exe-file" and "the executable" are the same thing, and thus whether sys.executableand sys.argv[0]are the same thing. Looking at code that worked for both script.py and py2exe_executable.exe last time I had to do this, I find something like:

从这些文档中看不出“exe 文件”和“可执行文件”是否是同一个东西,因此它们是否sys.executablesys.argv[0]是同一个东西。查看上次我必须执行此操作时对 script.py 和 py2exe_executable.exe 都有效的代码,我发现如下内容:

if hasattr(sys, 'frozen'):
    basis = sys.executable
else:
    basis = sys.argv[0]
required_folder = os.path.split(basis)[0]

As I say that worked, but I don't recall why I thought that was necessary instead of just using sys.argv[0].

正如我所说的那样有效,但我不记得为什么我认为这是必要的而不是仅仅使用sys.argv[0].

Using only basiswas adequate for the job in hand (read files in that directory). For a more permanent record, split something like os.path.realpath(basis).

仅使用basis足以完成手头的工作(读取该目录中的文件)。要获得更永久的记录,请拆分类似os.path.realpath(basis).

UpdateActually did a test; beats guesswork and armchair pontification :-)

更新实际上做了一个测试;胜过猜测和扶手椅式的崇高:-)

Summary: Ignore sys.frozen, ignore sys.executable, go with sys.argv[0] unconditionally.

总结:忽略sys.frozen,忽略sys.executable,无条件使用sys.argv[0]。

Evidence:

证据:

=== foo.py ===

=== foo.py ===

# coding: ascii
import sys, os.path
print 'sys has frozen:', hasattr(sys, 'frozen')
print 'using sys.executable:', repr(os.path.dirname(os.path.realpath(sys.executable)))
print 'using sys.argv[0]:',    repr(os.path.dirname(os.path.realpath(sys.argv[0]   )))

=== setup.py ===

=== setup.py ===

from distutils.core import setup
import py2exe
setup(console=['foo.py'])

=== results ===

=== 结果 ===

C:\junk\so\py2exe>\python26\python foo.py
sys has frozen: False
using sys.executable: 'C:\python26'
using sys.argv[0]: 'C:\junk\so\py2exe' # where foo.py lives

C:\junk\so\py2exe>dist\foo
sys has frozen: True
using sys.executable: 'C:\junk\so\py2exe\dist'
using sys.argv[0]: 'C:\junk\so\py2exe\dist' # where foo.exe lives

回答by VertigoRay

Py2exe does not define __file__: http://www.py2exe.org/index.cgi/Py2exeEnvironment

Py2exe 没有定义__file__http: //www.py2exe.org/index.cgi/Py2exeEnvironment

The OP requested a py2exe friendly version of:

OP 请求 py2exe 友好版本:

SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))

The best answer is to determine if python is frozen in an exe, py2exe has documentation on this: http://www.py2exe.org/index.cgi/HowToDetermineIfRunningFromExe

最好的答案是确定 python 是否在 exe 中被冻结,py2exe 有关于此的文档:http: //www.py2exe.org/index.cgi/HowToDetermineIfRunningFromExe

import imp, os, sys

def main_is_frozen():
   return (hasattr(sys, "frozen") or # new py2exe
           hasattr(sys, "importers") # old py2exe
           or imp.is_frozen("__main__")) # tools/freeze

def get_main_dir():
   if main_is_frozen():
       return os.path.dirname(sys.executable)
   return os.path.dirname(os.path.realpath(__file__))

SCRIPT_ROOT = get_main_dir()

Since, the python is EAFP, here's an EAFPversion ...

因为,python 是EAFP,这里是一个EAFP版本......

try:
   if sys.frozen or sys.importers:
      SCRIPT_ROOT = os.path.dirname(sys.executable)
except AttributeError:
   SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))

Cheers!

干杯!

回答by prestomation

Try this:

试试这个:

import os
import sys
os.path.realpath(os.path.dirname(sys.argv[0]))

回答by Siva Prakash

sys.argv[0]is a reliable way to get the path, as it will give the same result irrespective of being run as a script or exe . To get the directory os.path.dirname(sys.argv[0])

sys.argv[0]是获取路径的可靠方法,因为无论作为 script 还是 exe 运行,它都会给出相同的结果。获取目录os.path.dirname(sys.argv[0])

comparison between file and exe

文件和exe的比较