You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

类中生成器方法的时间戳装饰器实现: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:39:59