类中生成器方法的时间戳装饰器实现:self关键字冲突解决
解决类中生成器方法的装饰器self传递问题
你的问题核心出在装饰器的结构错误以及类内装饰器与实例方法的self参数冲突上,我来一步步帮你修正:
首先,先理清原代码的问题
不管是函数版还是类版,你写的装饰器都犯了一个关键错误:装饰器应该返回一个可调用的包装函数,而不是直接执行yield from wrapper()。函数版能运行只是巧合——它在装饰阶段就直接生成了生成器对象,而非返回一个可调用的方法,这种写法扩展性极差(比如原函数需要参数时直接失效)。
在类中时,这个错误加上类方法的self参数规则,就直接导致了冲突。
方案1:将装饰器定义在类外部(推荐)
这是最简洁的写法,避免类内装饰器的参数干扰:
from pprint import pprint from datetime import datetime def concat_datetime(func): def wrapper(self): # 只获取一次时间,避免同一个生成器中不同文档的日期/时间不一致 current_dt = datetime.now() for document in func(self): yield { **document, "current_date": current_dt.strftime("%Y-%m-%d"), "current_time": current_dt.strftime("%H:%M:%S"), } return wrapper # 关键:返回包装函数,而非直接执行它 class TestClass: @concat_datetime def test(self): yield { "a": "a", "b": "b", "c": "c" } obj = TestClass() # 注意:这里要调用obj.test(),因为装饰后它仍是一个方法,执行才会返回生成器 for doc in obj.test(): pprint(doc)
方案2:将装饰器定义在类内部(静态方法形式)
如果一定要把装饰器放在类里,需要将它标记为@staticmethod,这样就不会被自动传入类/实例的参数,避免和装饰器的func参数冲突:
from pprint import pprint from datetime import datetime class TestClass: @staticmethod def concat_datetime(func): def wrapper(self): current_dt = datetime.now() for document in func(self): yield { **document, "current_date": current_dt.strftime("%Y-%m-%d"), "current_time": current_dt.strftime("%H:%M:%S"), } return wrapper @concat_datetime def test(self): yield { "a": "a", "b": "b", "c": "c" } obj = TestClass() for doc in obj.test(): pprint(doc)
额外优化点
我在代码里加了current_dt = datetime.now()的逻辑,这样同一个生成器产出的所有文档都会使用同一时间,避免因为生成器执行耗时导致的日期/时间不一致问题。
内容的提问来源于stack exchange,提问作者Joe Doe
相关产品推荐
相关产品推荐

