Python中如何在静态方法内部获取自身的限定名__qualname__
解决方案
推荐两种实现方案,按你的场景适配即可:
方案1:装饰器方案(灵活可控)
直接在静态方法上挂载装饰器,定义阶段就提前获取__qualname__存好,运行时无需查栈,效率最高。
代码实现:
from functools import wraps def auto_gen_command(func): # 定义阶段直接获取完整限定名 qual_name = func.__qualname__ @wraps(func) def wrapper(*args, **kwargs): # 可保留原函数的业务逻辑 func(*args, **kwargs) # 按规则生成命令 output_path = kwargs.get("output_path") if kwargs else args[0] if args else "" return f"/{qual_name.replace('.', '/')}/ {output_path}" return wrapper
使用方式:
class file: class export: @staticmethod @auto_gen_command def ascii(output_path): # 原有业务逻辑写在这里,无需再手动拼接命令字符串 pass
测试效果:
print(file.export.ascii("test/output.txt")) # 输出:/file/export/ascii/ test/output.txt
方案2:元类方案(批量自动适配)
如果你有数百个这类静态方法,不想逐个加装饰器,可以用元类自动扫描所有嵌套类的静态方法,批量注入逻辑,完全不用修改原有方法代码。
代码实现:
from functools import wraps import inspect class CommandClassMeta(type): def __new__(cls, name, bases, attrs): # 遍历当前类的所有属性 for attr_name, attr_val in attrs.items(): # 处理静态方法 if isinstance(attr_val, staticmethod): raw_func = attr_val.__func__ qual_name = raw_func.__qualname__ @wraps(raw_func) def wrapper(*args, **kwargs): raw_func(*args, **kwargs) output_path = kwargs.get("output_path") if kwargs else args[0] if args else "" return f"/{qual_name.replace('.', '/')}/ {output_path}" attrs[attr_name] = staticmethod(wrapper) # 递归处理嵌套类 elif inspect.isclass(attr_val): attrs[attr_val.__name__] = CommandClassMeta( attr_val.__name__, attr_val.__bases__, dict(attr_val.__dict__) ) return super().__new__(cls, name, bases, attrs)
使用方式:
# 仅需给最外层的根类指定元类即可,所有嵌套类的静态方法自动适配 class file(metaclass=CommandClassMeta): class export: @staticmethod def ascii(output_path): # 原有代码完全不用改 pass class import: @staticmethod def csv(input_path): # 新增方法也不用加额外装饰器 pass
测试效果:
print(file.import.csv("data/input.csv")) # 输出:/file/import/csv/ data/input.csv
不推荐方案:运行时栈查询
如果一定要在方法内部实时获取,也可以通过栈反射实现,但效率低、重名函数会出错,仅做参考:
import inspect import sys def get_func_qualname(): caller_frame = inspect.currentframe().f_back func_name = caller_frame.f_code.co_name module = sys.modules[caller_frame.f_globals["__name__"]] # 递归遍历模块下所有类查找匹配的静态方法 def scan_class(cls): for attr_name, attr_val in cls.__dict__.items(): if isinstance(attr_val, staticmethod) and attr_val.__func__.__name__ == func_name: return attr_val.__func__.__qualname__ if inspect.isclass(attr_val): res = scan_class(attr_val) if res: return res return None for _, obj in inspect.getmembers(module, inspect.isclass): res = scan_class(obj) if res: return res return func_name
使用时在静态方法内调用qualname = get_func_qualname()即可。
内容的提问来源于stack exchange,提问作者Alwin
相关产品推荐
相关产品推荐

