類中方法的類裝飾器如何作業?這是我通過一些實驗所做的示例:
from functools import wraps
class PrintLog(object):
def __call__(self, func):
@wraps(func)
def wrapped(*args):
print('I am a log')
return func(*args)
return wrapped
class foo(object):
def __init__(self, rs: str) -> None:
self.ter = rs
@PrintLog()
def baz(self) -> None:
print('inside baz')
bar = foo('2')
print('running bar.baz()')
bar.baz()
這作業得很好。但是,我的印象是裝飾器不需要用 呼叫(),但是當我從 中洗掉括號時@PrintLog(),我收到此錯誤:
def baz(self) -> None:
TypeError: PrintLog() takes no arguments
有什么我遺漏/不明白的嗎?我也試過用 傳遞一個一次性引數__init__(),它有效。
class PrintLog(object):
def __init__(self, useless):
print(useless)
def __call__(self, func):
@wraps(func)
def wrapped(*args):
print('I am a log')
return func(*args)
return wrapped
class foo(object):
def __init__(self, rs: str) -> None:
self.ter = rs
@PrintLog("useless arg that I'm passing to __init__")
def baz(self) -> None:
print('inside baz')
同樣,這行得通,但我不想將任何引數傳遞給裝飾器。
tl;dr: python 3.x 中的這個問題。
幫助表示贊賞!
uj5u.com熱心網友回復:
類裝飾器接受函式作為__init__方法中的主題(因此是日志訊息),因此您的裝飾器代碼應如下所示:
class PrintLog(object):
def __init__(self, function):
self.function = function
def __call__(self):
@wraps(self.function)
def wrapped(*args):
print('I am a log')
return self.function(*args)
return wrapped
抱歉,如果這不起作用,我正在我的移動設備上回答。
編輯:
好的,這可能不是您想要的,但這是這樣做的方法:
from functools import update_wrapper, partial, wraps
class PrintLog(object):
def __init__(self, func):
update_wrapper(self, func)
self.func = func
def __get__(self, obj, objtype):
"""Support instance methods."""
return partial(self.__call__, obj)
def __call__(self, obj, *args, **kwargs):
@wraps(self.func)
def wrapped(*args):
print('I am a log')
return self.func(*args)
return wrapped(obj, *args)
class foo(object):
def __init__(self, rs: str) -> None:
self.ter = rs
@PrintLog
def baz(self) -> None:
print('inside baz')
bar = foo('2')
print('running bar.baz()')
bar.baz()
裝飾器必須__get__定義方法,因為您將裝飾器應用于實體方法。描述符如何擁有foo實體的背景關系?
參考:裝飾 Python 類方法 - 如何將實體傳遞給裝飾器?
uj5u.com熱心網友回復:
你錯過了一張大圖。
@decorator
def foo(...):
function_definition
幾乎相同(除了一些內部修改)
temp = foo
foo = decorator(temp)
裝飾器是什么并不重要,只要它可以像一個函式一樣作業。
你的例子相當于:
baz = PrintLog("useless thing")(<saved defn of baz>)
由于PrintLog是一個類,因此PrintLog(...)創建了 的實體PrintLog。該實體有一個__call__方法,所以它可以像一個函式一樣作業。
一些裝飾器被設計為接受引數。一些裝飾器被設計為不接受引數。有些,比如@lru_cache,是 Python 的魔法,它查看“引數”是一個函式(所以裝飾器被直接使用)還是一個數字/無,以便它回傳一個函式,然后成為裝飾器。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/371208.html
下一篇:未找到Weka過濾器類
