判断一个函数是否有装饰器
如何判断一个函数是否有装饰标记,如果有我们在pytest收集用例的时候能做一些什么操作呢
def my_decorator(func):def wrapper(*args, **kwargs):print("Function is being decorated!")return func(*args, **kwargs)return wrapper@my_decorator
def example_function():print("This is an example function.")def has_decorator(func):# 如果需要获取装饰器的源代码,可以通过函数的__closure__属性获取闭包closure = getattr(func, "__closure__", None)if closure:# 遍历闭包查找装饰器函数for cell in closure:if isinstance(cell.cell_contents, type(has_decorator)):# 返回找到的装饰器函数contents = cell.cell_contents# print(cell.cell_contents)# print(contents.__name__)# print(contents.__doc__)# print(contents.__code__)# print(contents.__code__.co_filename) # C:\Users\O_zhenhua.zhang\Desktop\cdc\vehiclecontroltools\vehicle_control_tools\dome.pyprint(contents.__code__.co_name) # my_decorator example_function# print(contents.__code__.co_firstlineno) # 第几行# print(contents.__code__.co_name) # my_decorator example_function# print(contents.__code__.co_lnotab) # 字节码 b'\x00\x02'# print(contents.__code__.co_lnotab)# print(contents.__code__.co_consts) # ('Function is being decorated!', 'This is an example function.')# print(contents.__code__.co_names) # ('print', 'func')return contents.__name__return None# Usage:
print(has_decorator(example_function)) # Should print True# Define another function without the decorator
def another_function():print("This is another function.")print(has_decorator(another_function)) # Should print False
装饰器文件
# add_class.py
def my_decorator(func):def wrapper(*args, **kwargs):print("Function is being decorated!")return func(*args, **kwargs)return wrapper
其他方法文件
# add_fun.py
from vehicle_control_tools.add_class import my_decorator@my_decorator
def test_function_with_decorator():passdef test_function_without_decorator():pass
conftest文件
import os
import inspect
import sysimport pytest
print(sys.path)def has_decorator(func):# 如果需要获取装饰器的源代码,可以通过函数的__closure__属性获取闭包closure = getattr(func, "__closure__", None)if closure:# 遍历闭包查找装饰器函数for cell in closure:if isinstance(cell.cell_contents, type(has_decorator)):# 返回找到的装饰器函数contents = cell.cell_contents# print(cell.cell_contents)# print(contents.__name__)# print(contents.__doc__)# print(contents.__code__)# print(contents.__code__.co_filename) # C:\Users\O_zhenhua.zhang\Desktop\cdc\vehiclecontroltools\vehicle_control_tools\dome.pyprint(contents.__code__.co_name) # my_decorator example_function# print(contents.__code__.co_firstlineno) # 第几行# print(contents.__code__.co_name) # my_decorator example_function# print(contents.__code__.co_lnotab) # 字节码 b'\x00\x02'# print(contents.__code__.co_lnotab)# print(contents.__code__.co_consts) # ('Function is being decorated!', 'This is an example function.')# print(contents.__code__.co_names) # ('print', 'func')return contents.__name__return Nonedef pytest_collection_modifyitems(session, config, items):ADD_FUN_FILE = 'add_fun' # 假设这是模块的文件名(不含.py后缀),且该文件位于Python的搜索路径中MODULE_PATH = ADD_FUN_FILE + '.py'# 检查add_fun.py文件是否存在if os.path.exists(MODULE_PATH):try:MODULE_DIR = r'C:\Users\O_zhenhua.zhang\Desktop\cdc\vehiclecontroltools\vehicle_control_tools'# 将模块所在的目录添加到sys.path中sys.path.append(MODULE_DIR)# 动态导入add_fun模块imported_module = pytest.importorskip(ADD_FUN_FILE)# 遍历模块中所有函数for name, obj in inspect.getmembers(imported_module, inspect.isfunction):# 检查函数是否有@add_class装饰器if has_decorator(obj):# # 添加到测试用例中# items.append(pytest.param(name, id=name))print(name)except Exception as e:print(f"An error occurred while importing or inspecting the module: {e}")else:print("add_fun.py does not exist.")