亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何通過`functools.wraps`從類裝飾器訪問裝飾類的屬性

如何通過`functools.wraps`從類裝飾器訪問裝飾類的屬性

呼喚遠方 2022-05-19 14:31:42
我正在關注David Beazley 的 Python Cookbook的 Class Decorator recipe,這似乎更合適,因為它用于functools.wraps為裝飾器提供更好的組織和屬性。但是,我不太清楚如何(或是否)從裝飾器本身訪問實例的屬性。這是代碼片段:import timeimport typesfrom functools import wrapsclass TimeDecorator():    def __init__(self, func):        wraps(func)(self)    def __call__(self, *args, **kwargs):        tic = time.time()        func_return = self.__wrapped__(*args, **kwargs)        tac = time.time()        total_time = round((tac - tic) / 60, 2)        print(f'Operation Time: {total_time} min.')        # print(self.__wrapped__.test_attr) # going to give an error...        return func_return    def __get__(self, instance, cls):        if instance is None:            return self        else:            return types.MethodType(self, instance)class A():    def __init__(self):        self.test_attr = 0    @TimeDecorator    def do_something(self):        time.sleep(1) # example of stuff only...我試圖__call__通過self.__wrapped__.test_attror訪問裝飾器的實例self.__wrapped__.__self__.test_attr,但它們都告訴我:AttributeError: 'function' object has no attribute 'test_attr'那么在這種情況下,我如何能夠訪問裝飾類的屬性呢?還是我必須使用另一種方式來構建我的裝飾器?
查看完整描述

2 回答

?
慕田峪9158850

TA貢獻1794條經驗 獲得超7個贊

您在實例方法上應用裝飾器,因此此裝飾方法綁定的實例將作為第一個參數傳入,self您可以在其中找到您要查找的實例屬性,因此您只需從參數中提取,在下面的示例中self命名wrapped_self:


def __call__(self, wrapped_self, *args, **kwargs):

    tic = time.time()

    func_return = self.__wrapped__(wrapped_self, *args, **kwargs)

    tac = time.time()

    total_time = round((tac - tic) / 60, 2)

    print(f'Operation Time: {total_time} min.')

    print(wrapped_self.test_attr)

    return func_return


查看完整回答
反對 回復 2022-05-19
?
慕尼黑8549860

TA貢獻1818條經驗 獲得超11個贊

“self”是 do_something 函數的第一個參數。


所以你可以在你的裝飾器中明確地識別它。 wrapped將是裝飾類實例,*args并將包含所有其他位置參數。


from functools import wraps

import types

import time


class TimeDecorator():


    def __init__(self, func):

        wraps(func)(self)


    def __call__(self, wrapped, *args, **kwargs):

        tic = time.time()

        func_return = self.__wrapped__(wrapped, *args, **kwargs)

        tac = time.time()

        total_time = round((tac - tic) / 60, 2)

        print(f'Operation Time: {total_time} min.')

        print(wrapped.test_attr)

        return func_return


    def __get__(self, instance, cls):

        if instance is None:

            return self

        else:

            return types.MethodType(self, instance)



class A():


    def __init__(self):

        self.test_attr = 0


    @TimeDecorator

    def do_something(self):

        time.sleep(1) # example of stuff only...




a = A()

a.do_something()


查看完整回答
反對 回復 2022-05-19
  • 2 回答
  • 0 關注
  • 177 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號