Python非测试代码场景下有没有类似Pytest.mark的标记功能库?
回答
你需要的这种给普通函数附加元标记、支持后续检索的功能,不需要额外引入第三方库,基于Python原生的装饰器和内省能力就能实现,整体逻辑非常轻量,和pytest标记的使用体验基本一致。
实现步骤
1. 自定义通用mark装饰器
支持无参标记(如@mark.refactor)和带参标记(如@mark.todo("备注内容")两种用法:
import functools import inspect class Mark: def __getattr__(self, marker_name): # 处理无参数的标记调用 def no_arg_decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs) if not hasattr(wrapper, "_markers"): wrapper._markers = {} wrapper._markers[marker_name] = True return wrapper # 处理带参数的标记调用 def with_arg_decorator(*args, **kwargs): def decorator(func): @functools.wraps(func) def wrapper(*f_args, **f_kwargs): return func(*f_args, **f_kwargs) if not hasattr(wrapper, "_markers"): wrapper._markers = {} wrapper._markers[marker_name] = args if args else kwargs return wrapper return decorator setattr(self, marker_name, with_arg_decorator) return no_arg_decorator mark = Mark()
2. 给普通函数加标记
用法和pytest的mark完全一致:
@mark.refactor def old_calculate(a, b): return a + b * 2 @mark.todo("下月替换为新的自研SDK") @mark.deprecated("v2.4版本后移除") def old_api_call(url): import requests return requests.get(url).json()
3. 实现标记扫描查询功能
写个简单的遍历脚本,就能查询项目下所有带指定标记的函数信息:
import os import importlib.util def scan_project_markers(project_root, target_marker=None): scan_result = [] # 遍历项目下所有py文件 for root, _, files in os.walk(project_root): for file in files: if not file.endswith(".py") or file.startswith("_"): continue file_path = os.path.join(root, file) # 加载模块 spec = importlib.util.spec_from_file_location(file[:-3], file_path) module = importlib.util.module_from_spec(spec) try: spec.loader.exec_module(module) except: # 跳过存在语法错误、加载失败的文件 continue # 提取模块内所有带标记的函数 for func_name, func_obj in inspect.getmembers(module, inspect.isfunction): if hasattr(func_obj, "_markers"): markers = func_obj._markers if target_marker is None or target_marker in markers: scan_result.append({ "file_path": file_path, "func_name": func_name, "line_no": inspect.getsourcelines(func_obj)[1], "markers": markers }) return scan_result if __name__ == "__main__": # 示例:查询所有带todo标记的函数 todo_list = scan_project_markers("./your_project_path", target_marker="todo") for item in todo_list: print(f"文件路径:{item['file_path']}") print(f"函数名:{item['func_name']},行号:{item['line_no']}") print(f"TODO备注:{item['markers']['todo'][0]}") print("---")
可选扩展
如果需要命令行直接查询,可以引入Python标准库的argparse做参数解析,就能实现类似python scan.py -m refactor的调用效果,和pytest的标记查询逻辑完全对齐。
内容的提问来源于stack exchange,提问作者voidbar
相关产品推荐
相关产品推荐

