Python装饰器工厂报错:'NoneType'对象不可调用问题排查
定时器装饰器工厂出现
TypeError: 'NoneType' object is not callable的解决方法 问题重现
你实现了一个带参数的定时器装饰器工厂,但在使用时遇到错误,错误触发在访问f.__name__的位置:
import time import typing as tp def timer(capture_duration: bool=False) -> tp.Callable: def decorator(f: tp.Callable) -> tp.Callable: def handle_args(*args, **kwargs): start = time.time() print("Starting " + f.__name__) # 错误发生在此处 ret = f(*args, **kwargs) end = time.time() print("Finished " + f.__name__ + f" in {end - start} seconds") if capture_duration: return (ret, end-start) else: return ret return handle_args return decorator
你的错误用法示例:
timer(capture_duration=True) def some_function_to_time(args): pass
错误原因
你的装饰器用法完全错误:
timer(capture_duration=True)调用后返回的是内部的decorator函数,这个函数需要接收被装饰的目标函数作为参数,才能生成最终的包装函数。- 你单独执行
timer(capture_duration=True)后,没有将其与some_function_to_time做任何关联,相当于这个调用没有实际作用;如果误将返回的decorator赋值给函数名(比如some_function_to_time = timer(capture_duration=True)),后续调用some_function_to_time时,会把调用参数传给decorator,导致decorator的参数f不是预期的函数(甚至为None),最终在handle_args中访问f.__name__时触发TypeError。
正确用法
方法1:使用装饰器标准@语法(推荐)
@timer(capture_duration=True) def some_function_to_time(args): pass
@timer(capture_duration=True)等价于some_function_to_time = timer(capture_duration=True)(some_function_to_time),会自动将目标函数传入装饰器工厂返回的decorator函数,生成包装后的函数。
方法2:手动调用装饰器绑定函数
如果不想用@语法,可手动完成装饰过程:
def some_function_to_time(args): pass # 先调用工厂获取decorator,再传入目标函数得到包装后的函数 some_function_to_time = timer(capture_duration=True)(some_function_to_time)
额外优化建议
为了保留原函数的元信息(比如__name__、__doc__),可以使用functools.wraps装饰包装函数handle_args,避免装饰后函数元信息丢失:
import time import typing as tp from functools import wraps def timer(capture_duration: bool=False) -> tp.Callable: def decorator(f: tp.Callable) -> tp.Callable: @wraps(f) def handle_args(*args, **kwargs): start = time.time() print(f"Starting {f.__name__}") ret = f(*args, **kwargs) end = time.time() print(f"Finished {f.__name__} in {end - start} seconds") if capture_duration: return (ret, end-start) else: return ret return handle_args return decorator
内容的提问来源于stack exchange,提问作者dauzzie
相关产品推荐
相关产品推荐

