如何动态获取当前执行的Python脚本名?

文章目录

1、情景描述

当我们在使用Python进行一些操作时,如果我们希望我们封装的模块里的方法能够在给使用者调用的同时可以获取到调用者当前正在执行的Python脚本名,以做一些后续操作。这听起来好像跟反射有异曲同工之处。反射可以实现吗?

来看一个需求:

现有一个用于封装工具API的模块:module.py,如下:

python 复制代码
def do():
    ...
    # 处理中间过程
    ...
    return 'result'

该模块中有一个方法do()供调用者调用。现在有一个需求:该方法中的处理中间过程需要获取到调用者当前执行的Python脚本名,并做一些处理操作,最后返回给调用者结果

这种情况需要如何实现呢?可以尝试以下办法:

2、如何获取调用者脚本名?

2.1、方式1:使用反射?

在Java中,我们知道反射是指在类加载时动态获取类的成员(包括类、属性、方法等),以对类和对象进行修改。在Python中,这类似。反射可以动态获取对象的属性和方法,但对于Python脚本,好像和它没啥关系吧?更何况Python脚本名呢

2.2、方式2:使用os模块?

Python内置的os模块提供一些文件和路径处理的方法,兴许这里面有可以帮我们完成这个需求的方法呢

os模块中的__file__属性可用于返回当前脚本的文件路径,包括文件名,结合os.path.basename()是否可以获取调用者的脚本名呢?马上进行下面尝试:

工具API模块:module.py

python 复制代码
import os

def do():
    print(os.path.basename(__file__))

调用者模块:client.py

python 复制代码
from module import do

do()

'''
module.py
'''

什么情况?我要获取的是调用者脚本名,我需要你打印出来的是client.py,而不是module.py

从结果可见,这种方式不太行啊

2.3、使用sys模块?

Python内置的sys模块主要用于Python解释器和系统之间的交互,例如获取系统环境变量。sys可以实现吗?

sys提供了一个函数sys._getframe()用于查看函数被什么函数调用及被第几行调用以及被调用函数所在的文件

sys._getframe(depth)从调用堆栈返回一个框架对象。 如果给定了可选整数depth,则返回在堆栈顶部以下调用多次的框架对象。depth的默认值为0,返回调用堆栈顶部的帧。如果参数比调用堆栈更深,则会引发ValueError异常

sys._getframe()的更多使用见文末总结

来试一下吧

工具API模块:module.py

python 复制代码
import os
import sys

def do():
    print(os.path.basename(sys._getframe().f_back.f_code.co_filename))

调用者模块:client.py

python 复制代码
from module import do

do()

'''
client.py
'''

嗯嗯,sys模块的sys._getframe()可以帮我们完成上述需求,但较为复杂,不好理解

2.4、sys获取argv

sys提供的sys.argv[]可用于访问命令行参数。然而,sys.argv[0]可用于获取正在执行的Python脚本本身

这可能是最好的一种方式。示例如下:

工具API模块:module.py

python 复制代码
import os
import sys

def do():
    print(os.path.basename(sys.argv[0]))

调用者模块:client.py

python 复制代码
from module import do

do()

'''
client.py
'''

这不是更完美吗?

3、sys._getframe()总结

sys._getframe()的常用使用总结如下:

python 复制代码
'''
sys._getframe(0)                       # 被调用模块层
sys._getframe(1)                       # 调用者模块层
sys._getframe().f_back                 # 调用者模块层,和sys._getframe(1)相同
sys._getframe(0).f_code.co_filename    # 被调用模块当前文件名,也可以通过__file__获得
sys._getframe(1).f_code.co_filename    # 调用者模块当前文件名,和sys._getframe().f_back.f_code.co_filename相同
sys._getframe(0).f_code.co_name        # 被调用模块层当前函数名
sys._getframe(1).f_code.co_name        # 调用者模块层调用所在函数名,如果没有,则返回<module>
sys._getframe(0).f_lineno              # 被调用模块层被调用函数的行号
sys._getframe(1).f_lineno              # 调用者模块层调用该函数所在的行号
'''
相关推荐
chao_7896 分钟前
动态规划题解——乘积最大子数组【LeetCode】
python·算法·leetcode·动态规划
倔强青铜三7 分钟前
苦练Python第20天:Python官方钦定的代码风格指南
人工智能·python·面试
倔强青铜三25 分钟前
苦练Python第19天:断言与自定义异常
人工智能·python·面试
荷蒲28 分钟前
【小白量化智能体】应用5:编写通达信股票交易指标及生成QMT自动交易Python策略程序
开发语言·python
大模型真好玩37 分钟前
深入浅出LangChain AI Agent智能体开发教程(一)—认识LangChain&LangGraph
人工智能·python·mcp
医工交叉实验工坊1 小时前
R 语言绘制 10 种精美火山图:转录组差异基因可视化
python·信息可视化·r语言
今天炼丹了吗3 小时前
RTDETR融合[WACV 2025]SEM-Net中的模块
python·深度学习·机器学习
这里有鱼汤3 小时前
一篇文章让你彻底搞懂量化中RSI指标,附实战策略+附源码,建议收藏
python
IIIIIII_II3 小时前
【视频格式转换】.264格式转为mp4格式
python·视频·格式转换
都叫我大帅哥3 小时前
LangChain的TXT文档加载:从入门到实战的终极指南
python·langchain