杰瑞科技汇

Python filename函数如何获取当前文件路径?

很多人会误以为它是一个函数,但实际上 __file__ 是一个 Python 内置变量,它存储了当前执行脚本的文件路径。

Python filename函数如何获取当前文件路径?-图1
(图片来源网络,侵删)

核心概念:__file__ 是什么?

__file__ 是一个全局变量,当 Python 解释器执行一个模块(通常是 .py 文件)时,这个变量就会被自动创建并赋值,它的值就是该模块源文件的路径。

重要提示__file__ 的行为会因 Python 的运行方式而异。


直接运行脚本

当你直接在命令行运行一个 Python 脚本时,__file__ 的值是脚本的相对路径或绝对路径。

示例:

Python filename函数如何获取当前文件路径?-图2
(图片来源网络,侵删)

假设你有一个文件结构如下:

/my_project/
└── main.py

main.py 的内容如下:

# main.py
import os
print(f"当前文件的路径是: {__file__}")
# 获取脚本所在的目录
script_dir = os.path.dirname(__file__)
print(f"脚本所在的目录是: {script_dir}")
# 获取脚本所在的绝对目录
abs_script_dir = os.path.abspath(script_dir)
print(f"脚本所在的绝对目录是: {abs_script_dir}")

在终端运行:

# 假设你当前在 /my_project 目录下
python main.py

输出结果:

Python filename函数如何获取当前文件路径?-图3
(图片来源网络,侵删)
当前文件的路径是: main.py
脚本所在的目录是: 
脚本所在的绝对目录是: /my_project

分析:

  • __file__main.py,这是一个相对路径
  • os.path.dirname(__file__) 获取了文件名之前的路径部分,因为 main.py 在当前工作目录,所以为空。
  • os.path.abspath() 将相对路径转换为了绝对路径。

作为模块导入

当你将一个脚本作为模块导入到另一个脚本中时,__file__ 的值是被导入模块的文件路径

示例:

文件结构如下:

/my_project/
├── main.py
└── utils/
    └── helper.py

utils/helper.py 的内容:

# utils/helper.py
import os
print(f"在 helper.py 中,__file__ 的值是: {__file__}")

main.py 的内容:

# main.py
import os
from utils import helper
print(f"在 main.py 中,__file__ 的值是: {__file__}")

在终端运行 main.py

python /my_project/main.py

输出结果:

在 helper.py 中,__file__ 的值是: /my_project/utils/helper.py
在 main.py 中,__file__ 的值是: /my_project/main.py

分析:

  • main.py 中,__file__ 指向 main.py 自身。
  • main.py 导入 helper.py 时,在 helper.py 的内部,__file__ 指向 helper.py 的完整路径。

在交互式解释器中

如果你在 Python 的交互式 shell (REPL) 中直接输入 __file__,会抛出 NameError,因为它不是一个全局变量,只有在模块被加载时才会被创建。

>>> __file__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name '__file__' is not defined

__file__ 的常见用途

__file__ 最常见的用途是确定脚本的位置,以便正确地访问其他文件,如配置文件、数据文件、日志文件等。

最佳实践:使用 pathlib 模块

现代 Python (3.4+) 推荐使用 pathlib 模块来处理路径,它比传统的 os.path 更直观、更强大。

示例:使用 pathlib

假设项目结构如下:

/my_project/
├── main.py
└── data/
    └── config.json

main.py 的内容:

# main.py
from pathlib import Path
# 获取当前脚本所在的目录
# Path(__file__).parent 等价于 os.path.dirname(__file__)
# 但 Path 对象可以进行更方便的操作
script_dir = Path(__file__).parent
# 构建配置文件的绝对路径
config_file_path = script_dir / 'data' / 'config.json'
print(f"当前脚本目录: {script_dir}")
print(f"配置文件路径: {config_file_path}")
# 检查文件是否存在
if config_file_path.exists():
    print("配置文件找到了!")
else:
    print("配置文件未找到!")
# 读取文件内容(仅作演示)
try:
    with open(config_file_path, 'r', encoding='utf-8') as f:
        print("\n文件内容:")
        print(f.read())
except FileNotFoundError:
    print("\n无法读取文件,因为它不存在。")

运行 main.py 后的输出:

当前脚本目录: /my_project
配置文件路径: /my_project/data/config.json
配置文件找到了!
{
  "database": "localhost",
  "port": 5432
}

重要注意事项:__file__ 的局限性

  1. 在打包后的应用中 (PyInstaller, PyOxidizer) 当你使用工具(如 PyInstaller)将你的 Python 程序打包成一个独立的可执行文件(如 .exe.app)后,__file__ 的行为会变得复杂,它可能指向一个临时的解压目录,而不是原始的脚本路径,在这种情况下,不应依赖 __file__ 来定位资源文件。

  2. __file__ 可能不是真实路径 在某些情况下(从标准输入读取代码,或者在交互式环境中运行代码片段),__file__ 可能不会被定义,或者其值可能不是你期望的文件路径('<stdin>''<string>'),在访问它之前最好进行检查。

    # 安全地使用 __file__
    if '__file__' in globals():
        script_dir = Path(__file__).parent
        # ... 进行后续操作 ...
    else:
        print("无法确定脚本路径,可能正在交互式环境中运行。")
        # 提供一个备选方案,例如使用当前工作目录
        script_dir = Path.cwd()
特性 描述
类型 内置变量,不是函数。
作用 存储当前执行的 Python 模块的源文件路径。
运行方式 直接运行脚本时,值为脚本的路径;作为模块导入时,值为被导入模块的路径。
主要用途 定位脚本自身,以便访问同目录或子目录下的其他文件(如配置、数据、日志等)。
推荐用法 结合 pathlib 模块 (Path(__file__).parent) 来安全、方便地处理文件路径。
局限性 在打包后的应用或某些非标准执行环境中可能不可靠或未定义。
分享:
扫描分享到社交APP
上一篇
下一篇