📜  如何在Python中获取当前脚本的目录?

📅  最后修改于: 2022-05-13 01:55:21.589000             🧑  作者: Mango

如何在Python中获取当前脚本的目录?

父目录是分层文件系统中另一个文件/目录上方的目录。获取父目录对于执行与文件系统管理相关的某些任务至关重要。在本文中,我们将了解用于获取当前正在运行的Python脚本的父目录的方法,并了解每种方法的各种用途/缺点。为了执行上述任务,我们将使用两个名为osinspect的库,这两个库都是内置的,因此不需要任何安装。

出于演示目的,我们将使用以下文件,该文件位于C:\suga\Lpath.py 。文件的内容(代码)将根据引用它的上下文进行更改。

我们将在以下示例中广泛使用os.path模块中的dirname()函数。因此,如果我们事先了解它会更好。

方法 1#:使用 __file__ 模块对象。

在这种方法中,我们将使用 __file__ (由双下划线 ( dunder ) 包围的文件关键字)。这个预定义的属性存在于大多数Python文件中。该属性用于获取当前正在执行的Python文件的文件名。我们将通过 __file__ 获得的路径传递给os.path.dirname()函数以获取Python文件的父目录。

Python3
import os
  
# Displaying the script path
print(__file__)
  
# Displaying the parent directory of the script
print(os.path.dirname(__file__))


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


Python3
from inspect import getsourcefile
  
import os
  
  
print(os.path.dirname(getsourcefile(lambda:0)))


输出:

C:\suga\Lpath.py
C:\suga

缺点:

  • 上述方法仅适用于在Python脚本中使用的情况。因此,如果从交互式环境 (stdin) 或逐行解释器(调试)运行,它将无法工作。
  • __file__ 不会出现在静态链接的 C 模块中(最初用 C 编写但移植到Python的库)
  • __file__ 不会在内置模块中定义

方法 2#:使用 sys.argv[0] 命令行参数

sys.argv是一个列表,其中包含传递给Python程序的命令行参数。在这个方法中,我们将使用 sys.argv 列表的第 0 个参数,即当前执行的Python文件的路径,来获取Python脚本的父目录。

蟒蛇3

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

输出:

C:\suga

缺点:

  • 上述方法仅适用于在Python脚本中使用sys.argv[0]的情况。它不适用于原始标准输入,例如。从Python命令行解释器 (IDLE) 运行命令。
  • 上述方法是基于参数的,因此如果Python脚本以特定方式运行,使得第一个参数(索引 0)不是可执行文件的文件名,则该方法将不起作用。前任。如果Lpath.py文件是使用命令“ py Lpath.py ”运行的,它会导致不显示任何输出。

方法 3#:使用 getsourcefile()函数

在这个方法中,我们将使用在检查库中找到的getsourcefile()方法来获取当前正在执行的Python脚本的绝对路径。然后我们将它传递给os.path.dirname()函数以获取文件名的父目录。这种方法通常是上述方法中最优化和最兼容的一种,因为它是跨平台、小规模(更少的代码行)并且在可变执行环境下工作的。

蟒蛇3

from inspect import getsourcefile
  
import os
  
  
print(os.path.dirname(getsourcefile(lambda:0)))

输出:

C:\suga

解释:

首先,我们导入了在检查库中找到的getsourcefile()函数。之后,我们导入了os库以使用其中找到的os.path.dirname()函数,该函数将用于从脚本文件名中提取父目录。我们提供lambda:0作为getsourcefile()函数的参数,因为它需要Python脚本中的引用对象,因此我们使用 lambda 创建了一个虚拟函数,只是为了使其能够在Python脚本中被引用。

注意:如果要在逐行解释器(例如 IDLE)中执行,上面的代码可能需要稍作修改(使用自函数,而不是dirname() )。但这超出了本文的范围。