簡體   English   中英

如何在 python 中創建裝飾器 class 的不同實例

[英]How to create different instances of decorator class in python

我目前正在嘗試實現一個裝飾器 class 來跟蹤我有 2 個實例的服務員 class 中的 function 調用。 我希望 2 個服務員實例有單獨的裝飾器實例 class 來跟蹤每個服務員的調用,這可能嗎?

代碼:

from functools import update_wrapper
import time

class decorater():
    """
    counts the number of calls and passes it into function
    """
    def __init__(self,func):
        self.func = func
        self.num_calls = 0
        update_wrapper(self, func)

    def __call__(self, *args, **kwargs):
        self.num_calls += 1
        result = self.func(self.num_calls, *args, **kwargs) # passes num_calls in for seconds
        print(f"total runs of {self.func.__name__}: {self.num_calls}")
        return result
    
class waiter():
    """
    waits for the number of seconds passed in
    """
    @decorater
    def wait_for(seconds, var_name):
        time.sleep(seconds)
        print(f"{var_name} waited for {seconds} seconds")

waiter1 = waiter()
waiter2 = waiter()

waiter1.wait_for("waiter1")
waiter2.wait_for("waiter2")

Output:

waiter1 waited for 1 seconds
total runs of wait_for: 1
waiter2 waited for 2 seconds
total runs of wait_for: 2

所需的 output:

waiter1 waited for 1 seconds
total runs of wait_for: 1
waiter2 waited for 1 seconds
total runs of wait_for: 1

裝飾器不應該按照您嘗試使用它們的方式使用,並且因為您已經創建了waiter class 的多個實例,為什么不直接處理每個實例中的所有內容而不是使用裝飾器呢?

像這樣的東西:

import time


class Waiter(object):
    """
    waits for the number of seconds passed in
    """

    def __init__(self, name):
        self.name = name
        self.num_calls = 0

    def wait(self):
        self.num_calls += 1
        print(f"total runs of {self.num_calls}")

        time.sleep(self.num_calls)
        print(f"{self.name} waited for {self.num_calls} seconds")


waiter1 = Waiter("waiter1")
waiter2 = Waiter("waiter2")

waiter1.wait()
waiter2.wait()

Output:

total runs of 1
waiter1 waited for 1 seconds
total runs of 1
waiter2 waited for 1 seconds

裝飾器可以是任何可調用的。

在您的代碼中,您使用了 class decorator本身(而不是其實例)作為裝飾器。 在這種情況下, decorator class 的__init__方法被調用,裝飾器 function 作為參數。

為了使用 class 的實例作為裝飾器,您必須將裝飾@decorator替換為@decorator() 這將導致調用decorator實例的__call__方法,並將裝飾的 function 作為參數。 當然,您必須調整__call__方法的簽名。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM