Python装饰器person_lister不使用inner函数能否实现同等效果?
问题
在如下Python代码实现中,装饰器person_lister(f)内部定义了用于处理人员列表people的inner(p)函数,请问是否可以不定义inner函数,就实现完全一致的运行效果?
def person_lister(f): def inner(p): return [f(i) for i in sorted(p, key=lambda l : l[2])] return inner @person_lister def name_format(person): return ("Mr. " if person[3] == "M" else "Ms. ") + person[0] + " " + person[1] if __name__ == '__main__': people = [input().split() for i in range(int(input()))] print(*name_format(people), sep='\n')
解答
完全可以,不定义inner函数也能实现一模一样的运行效果。
Python装饰器的核心规则非常简单:装饰器是接收被装饰函数作为入参的可调用对象,它的返回值会替换掉原被装饰函数,只要返回的可调用对象和原inner的入参规则、处理逻辑、返回值完全一致,运行效果就没有任何区别,语法上并没有强制要求必须在装饰器内部定义一个具名的嵌套函数。
针对这段代码的逻辑,最直接的改法是直接返回lambda匿名函数替代inner,代码如下:
def person_lister(f): return lambda p: [f(i) for i in sorted(p, key=lambda l: l[2])]
改完之后运行逻辑和原代码完全没有差异:装饰后的name_format接收人员列表参数,先按每条人员记录的第3个字段(索引为2,一般为年龄)排序,再逐个人调用原name_format逻辑格式化称谓和姓名,最终返回格式化后的字符串列表,和原代码的执行流程、输出结果完全一致。
当然这种写法只适合逻辑简单的场景,如果装饰器需要写多行逻辑、做异常处理、记录状态或者做复杂的参数校验,还是推荐用具名嵌套函数的写法,可读性和可维护性更高。
内容的提问来源于stack exchange,提问作者Pritesh Tadvi
相关产品推荐
相关产品推荐

