如何获取正在执行的冻结脚本的路径

9

如果您正在从与脚本不同的目录和驱动器运行经过冻结的Python脚本(使用py2exe进行冻结),那么确定执行脚本的路径的最佳方法是什么?

我尝试了一些解决方案:

inspect.getfile(inspect.currentframe())

问题:不返回完整路径,只返回脚本名称。
os.path.abspath( __file__ )

问题:在Windows上无法工作

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

问题: 返回空字符串。
os.path.abspath(inspect.getsourcefile(way3))

如果驱动器与pwd不同,则无法工作

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

如果驱动器与pwd不同,将无法工作

这是一个最小的不起作用的示例

D:\>path
PATH=c:\Python27\;c:\Users\abhibhat\Desktop\ToBeRemoved\spam\dist\;c:\gnuwin32\bin

D:\>cat c:\Users\abhibhat\Desktop\ToBeRemoved\spam\eggs.py
import os, inspect, sys
def way1():
    return os.path.dirname(sys.argv[0])

def way2():
    return inspect.getfile(inspect.currentframe())

def way3():
    return os.path.dirname(os.path.realpath(sys.argv[0]))

def way4():
    try:
        return os.path.abspath( __file__ )
    except NameError:
        return "Not Found"
def way5():
    return os.path.abspath(inspect.getsourcefile(way3))

if __name__ == '__main__':
    print "Path to this script is",way1()
    print "Path to this script is",way2()
    print "Path to this script is",way3()
    print "Path to this script is",way4()
    print "Path to this script is",way5()

D:\>eggs
Path to this script is
Path to this script is eggs.py
Path to this script is D:\
Path to this script is Not Found

相关问题:

注意:

@Fenikso的解决方案只适用于脚本与当前执行的驱动器相同的情况。当脚本在不同的驱动器上时,它将无法工作。

3个回答

12

当从另一个驱动器运行时,使用PATH也可以与cxFreeze一起使用的另一种方法:

import sys

if hasattr(sys, 'frozen'):
    print(sys.executable)
else:
    print(sys.argv[0])

来自Python:

H:\Python\Examples\cxfreeze\pwdme.py

从命令行:

D:\>h:\Python\Examples\cxfreeze\dist\pwdme.exe
h:\Python\Examples\cxfreeze\dist\pwdme.exe

使用 PATH 环境变量:

D:\>pwdme.exe
h:\Python\Examples\cxfreeze\dist\pwdme.exe

@Fenikso:这个完美地解决了问题。在发出这个问题之前,我已经在SO上看到了一些关于同样问题的参考资料,但是没有一个答案本身就是正确的。 - Abhijit

2

在我看来,根据绝对路径而执行不同操作的代码并不是一个好的解决方案。相对路径的解决方案可能会更好。使用dirname来确定相对目录,并使用os.sep实现跨平台兼容性。

if hasattr(sys, "frozen"):
    main_dir = os.path.dirname(sys.executable)
    full_real_path = os.path.realpath(sys.executable)
else:
    script_dir = os.path.dirname(__file__)
    main_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
    full_real_path = os.path.realpath(sys.argv[0])

冻结属性是Python标准。此外,还可以看一下Esky: http://pypi.python.org/pypi/esky

0

试试这个:

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

这是我使用的方法,与cx_Freeze一起使用,以获取实际运行.exe文件的目录。


如果脚本存在于不同的驱动器中,则此方法将无法正常工作。 - Abhijit
@Abhijit - 抱歉,我不明白。这是我所有冻结脚本的基本部分,从未失败过。你能描述一个它失败的例子吗? - Fenikso
我已经更新了示例以包括这种情况。如果驱动器不同,它只会返回您正在运行的驱动器名称。 - Abhijit
@Abhijit - 嗯。实际上,这就是 PATH 的用途,它改变了行为。而且,使用 cxFreeze 对我来说方式 2 实际上是有效的。 - Fenikso
请问您能详细说明一下“而且方式2对我来说确实有点起作用”的意思吗?您是说即使驱动器不同也可以使用这种方法吗? - Abhijit
我犯了一个错误。它返回h:\Python\Examples\cxfreeze\pwdme.py而不是h:\Python\Examples\cxfreeze\dist\pwdme.exe。请注意目录。 - Fenikso

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接