python踩坑: 装饰器类的局部缓冲值

发布时间 2023-07-14 16:52:36作者: hello-everybody

test.py:

# coding: utf8
import time
import threading
import functools


class MyThread(threading.Thread):
    def __init__(self, filename, fps):
        self.filename = filename
        self.fps = fps
        super().__init__()

    def run(self):
        print(f"filename: {self.filename}, fps: {self.fps}")
        time.sleep(1)


class MyDecorator:
    def __init__(self, filename_prefix, fps):
        self.filename = f"temp/{filename_prefix}_{time.time()}.log"
        self.fps = fps

    def __call__(self, func):
        def wrap(*args, **kwargs):
            thread = MyThread(filename=self.filename, fps=self.fps)
            thread.start()

            func(*args, **kwargs)

            thread.join()

        return wrap


def my_decorator(**kwargs):
    def outer(func):
        @functools.wraps(func)
        def inner(self):
            prefix = kwargs.get("prefix")
            filename = f"temp/{prefix}_{time.time()}.log"
            fps = kwargs.get("fps")

            thread = MyThread(filename=filename, fps=fps)
            thread.start()

            func(self)

            thread.join()

        return inner

    return outer


class Test:

    @MyDecorator(filename_prefix="process", fps=18)
    def process(self):
        for i in range(3):
            time.sleep(1)
            print("count:", i)

    @my_decorator(prefix="fun2", fps=18)
    def fun2(self):
        print("function 2")

    @MyDecorator(filename_prefix="process2", fps=18)
    def process2(self):
        for i in range(3):
            time.sleep(1)
            print("count:", i)


if __name__ == '__main__':
    obj = Test()
    obj.process()
    obj.fun2()
    obj.process2()
    print("==================")

    time.sleep(2)

    obj2 = Test()
    obj2.process()
    obj2.fun2()
    obj2.process2()

执行结果:

filename: temp/process_1689323409.5417378.log, fps: 18
count: 0
count: 1
count: 2
filename: temp/fun2_1689323412.567841.log, fps: 18
function 2

filename: temp/process2_1689323409.5417378.log, fps: 18
count: 0
count: 1
count: 2
==================
filename: temp/process_1689323409.5417378.log, fps: 18
count: 0
count: 1
count: 2
filename: temp/fun2_1689323421.6333349.log, fps: 18
function 2

filename: temp/process2_1689323409.5417378.log, fps: 18
count: 0
count: 1
count: 2

问题描述:

  1. 重复调用被装饰器类装饰的任意函数时,会自动使用第一次调用装饰器类时产生的局部缓冲值,例如:time.time()
  2. 使用装饰器函数不存在使用缓冲值的现象。

总结:
如非特别要求,尽可能使用装饰器函数,避免使用装饰器类。