首页 > 解决方案 > 如何在类中装饰生成器

问题描述

我正在尝试制作一个关于生成器的练习,并且我想在类的上下文中进行练习。

这是我正在使用的一些类,略过,因此它显示了概念并自行工作。如果某些东西在概念上没有多大意义,可能是因为我删除了代码以使其更短,所以请放过我(例如,这些类中的一些在示例中太小了,但它有助于我展示我的逻辑我希望在没有显示完整实现的情况下使用)。

class Account():
    amount = 0
    pass

class Client:
    def __init__(self,name):
        self.nombre = name
        self.account = Account()
    pass

import random
import time

class GeneratorClass():
    def __init__(self):
        self.names = ["james", "anna"]
        self.default_client = Client(self.names[0])

@log #I decorate the class method I want to modify its behaviour with the function log, explained below
    def generatorDataClient(self, nombre = "no"):
        client = self.default_client

        amount = client.account.amount

        while True:
            amount += random.randint(0, 2000)
            yield amount
            sleep = random.choice([1, 3, 5])
            time.sleep(sleep)

for i in GeneratorClass().generatorDataClient():
    print("hello, generating, kinda")

现在我想装饰 generatorDataClient(),例如记录对该函数的调用。为此,我尝试了几件事,其中一种方法如下:

def log(func):
    def wrapper(*args, **kwargs):
        func_str = func.__name__
        args_str = '| '.join(args)
        kwargs_str = '| '.join(str(kwargs))
        s_time = time.time()
        e_time = time.time()
        duration = e_time - s_time
        print("called '%s'(%r,%r) in %d time", func_str, args_str, kwargs_str, duration)
        return (yield from func(*args, **kwargs))
    return wrapper()

现在我被困在哪里:

我可以做类似的事情:

genobject3 = GeneratorClass()
generador3 = genobject3.generatorDataClient
for result in generador3:
    print("it was called ")

但我明白了TypeError: generatorDataClient() missing 1 required positional argument: 'self'

我已经尝试过其他一些事情,比如装饰实例对象等等,即使我让它工作,装饰器也只起作用一次,然后生成器继续做它的事情而没有修改行为。

有关如何解决此问题的任何帮助?我一直在看其他帖子,例如带有自参数的 Python 类方法装饰器?

如何在类中装饰方法?

decorator() 得到了一个意外的关键字参数

但到目前为止,试图模仿它们并没有奏效。

标签: pythonpython-3.xoopdecorator

解决方案


如果您的代码完全是这样,那么您不想调用wrapperin log,只需返回该函数。即更改为:

def log(func):
    def wrapper(*args, **kwds):
        # ....
        return (yield from func(*args, **kwargs))
    return wrapper

推荐阅读