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_ROOT
in 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__,因此我的脚本中断了。有谁知道如何解决或解决这个问题?
3 个解决方案
#1
22
Here is the py2exe documentation reference and here are the relevant items:
这是py2exe文档参考,以下是相关项目:
-
sys.executable
is set to the full pathname of the exe-file. - sys.executable设置为exe文件的完整路径名。
- The first item in
sys.argv
is the full pathname of the executable, the rest are the command line arguments. - sys.argv中的第一项是可执行文件的完整路径名,其余是命令行参数。
-
sys.frozen
only 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. - sys.frozen仅存在于可执行文件中。对于控制台可执行文件,它设置为“console_exe”,对于无控制台的gui可执行文件,设置为“windows_exe”,对于inprocess dll服务器,设置为“dll”。
-
__file__
is not defined (you might want to use sys.argv[0] instead) - __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.executable
and 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.executable和sys.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 basis
was adequate for the job in hand (read files in that directory). For a more permanent record, split something like os.path.realpath(basis)
.
仅使用基础就足以完成手头的工作(读取该目录中的文件)。对于更永久的记录,拆分类似os.path.realpath(basis)。
Update Actually did a test; beats guesswork and armchair pontification :-)
更新实际上做了一个测试;击败猜测和扶手椅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
#2
8
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 EAFP version ...
既然,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!
干杯!
#3
2
Try this:
尝试这个:
import os
import sys
os.path.realpath(os.path.dirname(sys.argv[0]))
#1
22
Here is the py2exe documentation reference and here are the relevant items:
这是py2exe文档参考,以下是相关项目:
-
sys.executable
is set to the full pathname of the exe-file. - sys.executable设置为exe文件的完整路径名。
- The first item in
sys.argv
is the full pathname of the executable, the rest are the command line arguments. - sys.argv中的第一项是可执行文件的完整路径名,其余是命令行参数。
-
sys.frozen
only 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. - sys.frozen仅存在于可执行文件中。对于控制台可执行文件,它设置为“console_exe”,对于无控制台的gui可执行文件,设置为“windows_exe”,对于inprocess dll服务器,设置为“dll”。
-
__file__
is not defined (you might want to use sys.argv[0] instead) - __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.executable
and 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.executable和sys.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 basis
was adequate for the job in hand (read files in that directory). For a more permanent record, split something like os.path.realpath(basis)
.
仅使用基础就足以完成手头的工作(读取该目录中的文件)。对于更永久的记录,拆分类似os.path.realpath(basis)。
Update Actually did a test; beats guesswork and armchair pontification :-)
更新实际上做了一个测试;击败猜测和扶手椅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
#2
8
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 EAFP version ...
既然,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!
干杯!
#3
2
Try this:
尝试这个:
import os
import sys
os.path.realpath(os.path.dirname(sys.argv[0]))