Как украсить генератор внутри класса - PullRequest
0 голосов
/ 07 ноября 2019

Я пытаюсь составить упражнение о генераторах, и я хотел сделать это в контексте классов.

Это некоторые из классов, которые я использую, уменьшенные, поэтому они показывают концепцию иработает само по себе. Если что-то не имеет смысла в концептуальном, то это может быть потому, что я удалил код, чтобы сделать его короче, поэтому, пожалуйста, избавьте меня (например, некоторые из этих классов слишком малы в примере, но это помогает мне показать логику, которую яя использую, не показывая полную реализацию, я надеюсь).

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 () получил неожиданный аргумент ключевого слова

Но попытка эмулировать их пока не работает.

1 Ответ

1 голос
/ 07 ноября 2019

если ваш код в точности такой, то вы не хотите вызывать wrapper в log, просто верните функцию. т.е. измените его на:

def log(func):
    def wrapper(*args, **kwds):
        # ....
        return (yield from func(*args, **kwargs))
    return wrapper
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...