如何动态获取当前执行的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              # 调用者模块层调用该函数所在的行号
'''
相关推荐
哇咔咔哇咔5 分钟前
【科普】conda、virtualenv, venv分别是什么?它们之间有什么区别?
python·conda·virtualenv
CSXB9927 分钟前
三十四、Python基础语法(文件操作-上)
开发语言·python·功能测试·测试工具
亚图跨际1 小时前
MATLAB和Python及R潜变量模型和降维
python·matlab·r语言·生物学·潜变量模型
IT古董1 小时前
【机器学习】决定系数(R²:Coefficient of Determination)
人工智能·python·机器学习
德育处主任Pro1 小时前
『Django』APIView基于类的用法
后端·python·django
Star Patrick2 小时前
算法训练(leetcode)二刷第十九天 | *39. 组合总和、*40. 组合总和 II、*131. 分割回文串
python·算法·leetcode
武子康3 小时前
大数据-213 数据挖掘 机器学习理论 - KMeans Python 实现 距离计算函数 质心函数 聚类函数
大数据·人工智能·python·机器学习·数据挖掘·scikit-learn·kmeans
写点什么啦3 小时前
使用R语言survminer获取生存分析高风险和低风险的最佳截断值cut-off
开发语言·python·r语言·生存分析·x-tile
武子康3 小时前
大数据-214 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn n_clusters labels
大数据·人工智能·python·深度学习·算法·机器学习·数据挖掘
封步宇AIGC4 小时前
量化交易系统开发-实时行情自动化交易-Okex K线数据
人工智能·python·机器学习·数据挖掘