使用装饰器按元组末尾元素升序排序列表的代码报错排查
解决装饰器实现元组按最后元素排序的错误
错误原因分析
- 装饰器缺少返回值:
parapassing_decorator函数定义了内层的getSortedElement装饰器函数,但没有返回它。当使用@parapassing_decorator(...)语法时,该调用返回None,Python会把getlastelements赋值为None,后续调用自然触发NoneType不可调用的错误。 - 原函数逻辑错误:
getlastelements的循环在第一次迭代时就执行return,根本没遍历所有元组;同时依赖全局变量List2,会导致多次调用时数据污染。 - 排序逻辑完全错误:装饰器中的列表推导式逻辑混乱,没有实现按元组最后一个元素排序的功能,仅做了无意义的匹配操作。
修正后的代码实现
我们重构代码,用标准装饰器实现需求,避免全局变量和逻辑混乱:
import functools def sort_by_last_element(func): @functools.wraps(func) def wrapper(*args, **kwargs): # 调用原函数获取元组列表 tuple_list = func(*args, **kwargs) # 按元组最后一个元素升序排序 sorted_list = sorted(tuple_list, key=lambda x: x[-1]) return sorted_list return wrapper @sort_by_last_element def process_tuple_list(input_list): # 原函数可负责输入预处理,此处直接返回输入示例 return input_list # 调用示例 result = process_tuple_list([(2, 5), (1, 2), (4, 4), (2, 3), (2, 1)]) print(result) # 输出: [(2, 1), (1, 2), (2, 3), (4, 4), (2, 5)]
代码说明
- 装饰器
sort_by_last_element是标准无参数装饰器,接收被装饰函数后返回包装函数wrapper。 wrapper函数先调用原函数获取元组列表,再通过sorted函数的key参数指定按元组最后一个元素排序。- 原函数
process_tuple_list不再依赖全局变量,可根据需求添加输入预处理逻辑,此处仅返回输入示例。
原装饰器的最小修复(不推荐)
如果一定要基于原装饰器结构修改,需先补全返回值,再修正排序逻辑,但这种方式存在参数冗余问题:
import functools def parapassing_decorator(tuple1): def getSortedElement(func): @functools.wraps(func) def inner1(*args, **kwargs): # 按元组最后一个元素排序 sorted_list = sorted(tuple1, key=lambda x: x[-1]) return sorted_list return inner1 return getSortedElement # 必须返回内层装饰器函数 @parapassing_decorator(tuple1=[(2, 5), (1, 2), (4, 4), (2, 3), (2, 1)]) def getlastelements(tuple1): return tuple1 # 调用示例 result = getlastelements(tuple1=[(2, 5), (1, 2), (4, 4), (2, 3), (2, 1)]) print(result)
内容的提问来源于stack exchange,提问作者Sangita Paul
相关产品推荐
相关产品推荐

