3 回答

TA貢獻(xiàn)1863條經(jīng)驗(yàn) 獲得超2個(gè)贊
如果您無法控制裝飾器的功能,則通常無法確定裝飾器的方法。
但是,由于可以修改serializable,因此可以將屬性添加到包裝的函數(shù)中,以供以后標(biāo)識(shí)序列化方法時(shí)使用:
import inspect
def serializable(func):
def wrapper(self):
pass
wrapper.serialized = True
return wrapper
class Book:
@serializable
def pretty_status(self):
pass
def foo(self):
pass
for name, member in inspect.getmembers(Book, inspect.ismethod):
if getattr(member, 'serialized', False):
print(name, member)
產(chǎn)量
('pretty_status', <unbound method Book.wrapper>)

TA貢獻(xiàn)1775條經(jīng)驗(yàn) 獲得超11個(gè)贊
一般來說,您不能。裝飾器只是用于應(yīng)用可調(diào)用對象的語法糖。在您的情況下,裝飾器語法會(huì)轉(zhuǎn)換為:
def pretty_status(self):
return [b for a, b in BOOK_STATUS_CHOICES if a == self.status][0]
pretty_status = serializable(pretty_status)
也就是說,pretty_status被任何serializable()回報(bào)所取代。它返回的可能是任何東西。
現(xiàn)在,如果serializable返回值本身已經(jīng)被修飾,functools.wraps()并且您正在使用Python 3.2或更高版本,那么您可以看到.__wrapped__new.pretty_status方法上是否有一個(gè)屬性;它是對原始包裝函數(shù)的引用。
在早期版本的Python上,您也可以輕松地自己執(zhí)行此操作:
def serializable(func):
def wrapper(*args, **kw):
# ...
wrapper.__wrapped__ = func
return wrapper
您可以向該包裝函數(shù)添加任意數(shù)量的屬性,包括您自己選擇的自定義屬性:
def serializable(func):
def wrapper(*args, **kw):
# ...
wrapper._serializable = True
return wrapper
然后測試該屬性:
if getattr(method, '_serializable', False):
print "Method decorated with the @serializable decorator"
您可以做的最后一件事是測試該包裝器函數(shù);它會(huì)有一個(gè).__name__可以測試的屬性。該名稱可能不是唯一的,但這只是一個(gè)開始。
在上面的示例裝飾器中,包裝函數(shù)稱為wrapper,因此pretty_status.__name__ == 'wrapper'將為True。

TA貢獻(xiàn)1846條經(jīng)驗(yàn) 獲得超7個(gè)贊
您不能直接發(fā)現(xiàn)它們,但是可以用一些標(biāo)志標(biāo)記修飾的方法。
import functools
def serializable(func):
functools.wraps(func)
def wrapper(*args, **kw):
# ...
wrapper._serializable = True
return wrapper
然后,您可以使元類例如分析_serializable屬性的存在或不存在。
或者您可以在裝飾器中收集所有包裝的方法
import functools
DECORATED = {}
def serializable(func):
functools.wraps(func)
def wrapper(*args, **kw):
# ...
DECORATED[func.__name__] = wrapper
return wrapper
添加回答
舉報(bào)