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

Chr*_*son 17 python py2exe

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

SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))
Run Code Online (Sandbox Code Playgroud)

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

Joh*_*hin 22

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

  • sys.executable 设置为exe文件的完整路径名.
  • 第一项sys.argv是可执行文件的完整路径名,其余是命令行参数.
  • sys.frozen仅存在于可执行文件中.对于控制台可执行文件,它设置为"console_exe",对于无控制台的gui可执行文件,设置为"windows_exe",对于inprocess dll服务器,设置为"dll".
  • __file__ 未定义(您可能希望使用sys.argv [0])

它不是从这些文档显而易见"的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]
Run Code Online (Sandbox Code Playgroud)

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

仅使用适用basis于手头的工作(读取该目录中的文件).对于更永久的记录,分开类似的东西os.path.realpath(basis).

更新实际上做了一个测试; 猜测和扶手椅pontification :-)

摘要:忽略sys.frozen,忽略sys.executable,无条件地使用sys.argv [0].

证据:

=== 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]   )))
Run Code Online (Sandbox Code Playgroud)

=== setup.py ===

from distutils.core import setup
import py2exe
setup(console=['foo.py'])
Run Code Online (Sandbox Code Playgroud)

===结果===

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
Run Code Online (Sandbox Code Playgroud)


Ver*_*Ray 8

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

OP要求py2exe友好版本:

SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))
Run Code Online (Sandbox Code Playgroud)

最好的答案是确定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()
Run Code Online (Sandbox Code Playgroud)

既然,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__))
Run Code Online (Sandbox Code Playgroud)

干杯!


pre*_*ion 3

尝试这个:

import os
import sys
os.path.realpath(os.path.dirname(sys.argv[0]))
Run Code Online (Sandbox Code Playgroud)