如何动态获取当前执行的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              # 调用者模块层调用该函数所在的行号
'''
相关推荐
大懒猫软件3 小时前
如何运用python爬虫获取大型资讯类网站文章,并同时导出pdf或word格式文本?
python·深度学习·自然语言处理·网络爬虫
XianxinMao4 小时前
RLHF技术应用探析:从安全任务到高阶能力提升
人工智能·python·算法
查理零世5 小时前
【算法】经典博弈论问题——巴什博弈 python
开发语言·python·算法
汤姆和佩琦6 小时前
2025-1-21-sklearn学习(43) 使用 scikit-learn 介绍机器学习 楼上阑干横斗柄,寒露人远鸡相应。
人工智能·python·学习·机器学习·scikit-learn·sklearn
HyperAI超神经6 小时前
【TVM教程】为 ARM CPU 自动调优卷积网络
arm开发·人工智能·python·深度学习·机器学习·tvm·编译器
缺的不是资料,是学习的心7 小时前
使用qwen作为基座训练分类大模型
python·机器学习·分类
Zda天天爱打卡8 小时前
【机器学习实战中阶】使用Python和OpenCV进行手语识别
人工智能·python·深度学习·opencv·机器学习
martian6658 小时前
第19篇:python高级编程进阶:使用Flask进行Web开发
开发语言·python
gis收藏家8 小时前
利用 SAM2 模型探测卫星图像中的农田边界
开发语言·python
YiSLWLL8 小时前
Tauri2+Leptos开发桌面应用--绘制图形、制作GIF动画和mp4视频
python·rust·ffmpeg·音视频·matplotlib