如何在Python函数内部获取自身函数名以避免硬编码?
如何在Python中无需硬编码获取当前函数名?
嘿,我明白你想要的是不用每次手动写死函数名,就能在每个DBworker函数里打印它的启动和结束日志对吧?之前看了相关内容还有疑问,那我给你几种实用的实现方式,完全不用硬编码函数名:
方法1:利用sys._getframe()直接获取当前函数名
这是最直接的方式,不用额外定义装饰器,直接在函数内部获取当前栈帧的函数名:
import sys def DBworker_thatdoes_job7(): func_name = sys._getframe().f_code.co_name print(f"{func_name} starting...") # 你的实际业务代码 print(f"{func_name} finished.") def DBworker_thatdoes_cleaning18(): func_name = sys._getframe().f_code.co_name print(f"{func_name} starting...") # 你的实际业务代码 print(f"{func_name} finished.")
不过要注意,sys._getframe()是Python的内部函数(名字带下划线),虽然在标准CPython环境下完全可用,但在一些替代实现(比如PyPy)里可能有差异,这点要留意。
方法2:用装饰器抽离日志逻辑(更优雅)
如果有很多这类DBworker函数,推荐用装饰器把日志逻辑抽离出来,这样每个函数只需要加个装饰器,不用重复写打印代码,符合DRY原则:
def log_function_lifecycle(func): def wrapper(*args, **kwargs): # 获取被装饰函数的名字 func_name = func.__name__ print(f"{func_name} starting...") # 执行原函数逻辑 result = func(*args, **kwargs) print(f"{func_name} finished.") return result return wrapper # 给每个DBworker函数加上装饰器 @log_function_lifecycle def DBworker_thatdoes_job7(): # 你的实际业务代码 pass @log_function_lifecycle def DBworker_thatdoes_cleaning18(): # 你的实际业务代码 pass
这种方式的好处是,后续新增DBworker函数时,只需要加个装饰器就行,不用再写一遍日志打印的代码,维护起来更方便。
方法3:用inspect模块获取函数名
还有一种更“正规”的方式是用inspect模块,它专门用于获取对象的信息,包括函数:
import inspect def DBworker_thatdoes_job7(): func_name = inspect.currentframe().f_code.co_name print(f"{func_name} starting...") # 你的实际业务代码 print(f"{func_name} finished.")
其实inspect.currentframe()本质上和sys._getframe(0)是一样的,只是inspect模块提供了更统一的API来处理这类反射操作。
内容的提问来源于stack exchange,提问作者Basj
相关产品推荐
相关产品推荐

