在python中,如何获取脚本文件所在路径-2

来源:互联网 发布:封印者n卡优化 编辑:程序博客网 时间:2024/05/17 18:02

From: http://blog.csdn.NET/bupteinstein/article/details/6534177

在Python中,如何获取脚本文件所在路径?

首先说明,不是获取“当前路径”,即os.getcwd()

这个问题包括两个容易混淆的问题,一是获取当前脚本文件所在的路径,二是获取启动python解释器的脚本所在的路径。

获取当前脚本文件所在路径,解决方案是1、2、3

获取启动python解释器的脚本文件所在路径,解决方案是4

当当前脚本是被直接运行的脚本(而不是被当作模块调用)时,两个问题的结果是一样的。

使用cx_freeze将脚本转换为可执行文件后,每种方案都会遇到自己的问题,不能在所有情况下都正确地获取当前文件路径。所以将几种办法结合起来,得到解决方案5,解决了所有问题。

 
    1. 获取调用该函数的脚本所在路径,跨模块跨文件可调用的函数:
    使用python解释器运行没有问题,编译成为exe后有问题,显示出来的是"当前路径",但不知道是为什么。我打印了一下inspect.stack(),发现文件名都对,但路径都是调用时的“当前路径”,不知道为什么?

 

        # function: get the directory of script that calls this function
        # usage: path = script_path()
        def script_path():
            import inspect, os
            caller_file = inspect.stack()[1][1]         # caller's filename
            return os.path.abspath(os.path.dirname(caller_file))# path

 

    2. 得到定义该函数的脚本路径,多文件使用要拷贝多份:

 

        # function: get absolute directory of the file
        #   in which this function defines
        # usage: path = script_path()
        # note: please copy the function to target script,
        #   don't use it like <module>.script_path()
        def script_path():
            import inspect, os
            this_file = inspect.getfile(inspect.currentframe())
            return os.path.abspath(os.path.dirname(this_file))

 

    3. 使用模块内置成员变量,但文件经cx_freeze编译为可执行文件后就会报错,说找不到变量定义(或为内置模块,无对应成员):

 

        # warning: 编译为exe后,报错:找不到__file__定义
        # usage: path = script_path(__file__)
        def script_path(file_macro):
            return os.path.abspath(os.path.dirname(file_macro))

 

        # warning: 编译为exe后,报错:模块没有__file__属性
        # usage: path = script_path(__name__)
        def script_path(__name__):
            return os.path.abspath(os.path.dirname(
                        sys.modules[__name__].__file__))

 

        # warning: 编译为exe后,抛出异常:模块为内置模块,无法使用getfile获取文件名
        # usage: path = script_path(__name__)
        def script_path(__name__):
            import inspect
            return os.path.abspath(inspect.getfile(sys.modules[__name__]))

 

    4. 获取启动python解释器的脚本路径:

 

        def script_path():
            path = os.path.realpath(sys.path[0])
            if os.path.isfile(path):
                path = os.path.dirname(path)
            return os.path.abspath(path)

 

    5. 综合遇到的问题,将以上方法结合起来:如果在可执行文件中,则返回可执行文件所在路径。如果在脚本中,则返回调用函数的脚本所在路径。

        但这样也有问题,我发现inspect.stack()记录的路径都是相对路径,相对于启动时的os.getcwd()。所以如果使用了os.chdir(),那就会错误。

 

        # function: get directory of current script, if script is built
        #   into an executable file, get directory of the excutable file
        def current_file_directory():
            import os, sys, inspect
            path = os.path.realpath(sys.path[0])        # interpreter starter's path
            if os.path.isfile(path):                    # starter is excutable file
                path = os.path.dirname(path)
                return os.path.abspath(path)            # return excutable file's directory
            else:                                       # starter is python script
                caller_file = inspect.stack()[1][1]     # function caller's filename
                return os.path.abspath(os.path.dirname(caller_file))# return function caller's file's directory

0 0
原创粉丝点击