You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 01:57:00