如何將類字段作爲參數傳遞給類方法上的裝飾器?我想要做的是這樣的:具有自我參數的Python類方法裝飾器?
class Client(object):
def __init__(self, url):
self.url = url
@check_authorization("some_attr", self.url)
def get(self):
do_work()
它抱怨自我不存在self.url傳遞給裝飾。有沒有解決的辦法?
如何將類字段作爲參數傳遞給類方法上的裝飾器?我想要做的是這樣的:具有自我參數的Python類方法裝飾器?
class Client(object):
def __init__(self, url):
self.url = url
@check_authorization("some_attr", self.url)
def get(self):
do_work()
它抱怨自我不存在self.url傳遞給裝飾。有沒有解決的辦法?
是的。而不是在類定義時間傳入實例屬性,請在運行時檢查它:
def check_authorization(f):
def wrapper(*args):
print args[0].url
return f(*args)
return wrapper
class Client(object):
def __init__(self, url):
self.url = url
@check_authorization
def get(self):
print 'get'
>>> Client('http://www.google.com').get()
http://www.google.com
get
裝飾器攔截方法參數;第一個參數是實例,所以它讀取該屬性。您可以在屬性名作爲一個字符串傳遞給裝飾和使用getattr
如果你不想硬編碼的屬性名稱:
def check_authorization(attribute):
def _check_authorization(f):
def wrapper(self, *args):
print getattr(self, attribute)
return f(self, *args)
return wrapper
return _check_authorization
你不行。在課堂上沒有self
,因爲沒有實例存在。您需要傳遞它,例如str
,其中包含要在實例上查找的屬性名稱,然後返回的函數可以執行此操作,或者完全使用其他方法。
from re import search
from functools import wraps
def is_match(_lambda, pattern):
def wrapper(f):
@wraps(f)
def wrapped(self, *f_args, **f_kwargs):
if callable(_lambda) and search(pattern, (_lambda(self) or '')):
f(self, *f_args, **f_kwargs)
return wrapped
return wrapper
class MyTest(object):
def __init__(self):
self.name = 'foo'
self.surname = 'bar'
@is_match(lambda x: x.name, 'foo')
@is_match(lambda x: x.surname, 'foo')
def my_rule(self):
print 'my_rule : ok'
@is_match(lambda x: x.name, 'foo')
@is_match(lambda x: x.surname, 'bar')
def my_rule2(self):
print 'my_rule2 : ok'
test = MyTest()
test.my_rule()
test.my_rule2()
輸出繼電器: my_rule2:OK
非常感謝你!這應該是被接受的答案。我正在試圖弄清裝飾者的類別方法。 – benshepherd 2017-03-09 12:04:42
@raphael在這個設置中,我似乎無法訪問_lambda或模式。我該如何補救。 – Jonathan 2018-01-18 17:03:32
更簡潔的例子可能如下:
#/usr/bin/env python3
from functools import wraps
def wrapper(method):
@wraps(method)
def _impl(self, *method_args, **method_kwargs):
return method(self, *method_args, **method_kwargs) + "!"
return _impl
class Foo:
@wrapper
def bar(self, word):
return word
f = Foo()
result = f.bar("kitty")
print(result)
,它將打印:
kitty!
這是一個你有控制權的自定義裝飾器,還是一個你不能改變的裝飾器? – 2012-07-30 23:35:30
這是我的裝飾器,所以我完全控制它 – Mark 2012-07-30 23:36:19
它在init之前被調用我認爲是問題... – 2012-07-30 23:37:57