使用exec()执行脚本时如何获取当前脚本的正确路径?
问题描述
当通过exec()从一个Python文件调用执行另一个Python文件时,__file__属性指向的是调用者文件的路径,而非被调用者的路径。示例如下:
caller.py
with open("callee.py", "r") as callee: exec(callee.read(), globals(), locals())
callee.py
print("this file is:", __file__)
实际输出结果为:
this file is: caller.py
而非预期的:
this file is: callee.py
如何在被exec()执行时获取当前执行文件的路径?
解决方案
方法1:手动传入__file__到被执行脚本的命名空间
在调用exec()时,主动在全局命名空间参数中传入被执行文件的路径,覆盖默认继承的调用者__file__:
修改后的caller.py:
with open("callee.py", "r") as callee: # 传入被执行文件的路径到globals字典 exec(callee.read(), {"__file__": "callee.py"}, locals())
此时运行caller.py,输出会变为预期的:
this file is: callee.py
方法2:传入绝对路径(更可靠)
如果被执行文件的路径可能存在相对路径问题,建议先获取其绝对路径再传入,避免因工作目录变化导致的路径错误:
修改后的caller.py:
import os # 获取被执行文件的绝对路径 callee_file_path = os.path.abspath("callee.py") with open(callee_file_path, "r") as callee: exec(callee.read(), {"__file__": callee_file_path}, locals())
这种方式输出的是文件的完整绝对路径,适用性更强。
原理说明
exec()默认会继承调用者的全局命名空间,因此被执行脚本中的__file__会直接使用调用者的该变量值。通过手动在exec()的第一个字典参数(全局命名空间)中指定__file__,就能让被执行脚本获取到自身的文件路径。
内容的提问来源于stack exchange,提问作者Periodic Maintenance
相关产品推荐
相关产品推荐

