也許我想要做的只是不起作用。我也假設有其他(更好的)方法來完成相同的事情,但我想要做的是:使用「替換」功能時的多個Python裝飾器
我有一個類,將有幾個(至少4,可能更多)列表字典。我想設置一個「加載」功能和一個可用於所有這些功能的搜索功能。如果調用了任何「加載」或搜索功能,並且列表爲空,則應加載列表。
加載它們的方法各不相同,並且具有不同的參數。搜索功能需要允許搜索構成列表的字典的不同成員,並返回整個匹配字典或特定成員。
我一直在使用裝飾以指定搜索功能ALA:
@search_list
def get_name(self,id):
pass
讓我有效替代與搜索功能,並且可以使用func.__name__
在搜索功能,以確定從哪個列表類使用什麼成員,如果有的話(函數名稱末尾的_xx
),返回。
我遇到的問題是,做這樣的事情的時候,我可以使用加載功能,get_list()
,本身:
@get_list
def get_names(self):
return self.names
但我一直沒能得到它加載列表,如果我首先調用的是搜索功能之一。如果我調用@get_list
函數之一,那麼搜索函數在那之後可以正常工作,但我不想調用加載函數,除非有人使用該模塊需要該特定列表。所有列表都通過REST調用加載,有些則需要一段時間。
就像我說的,可能還有其他(更好)的方式來做到這一點,但是這已經讓我瘋了......這是一次短暫的旅行:-)
任何建議,將不勝感激。
這是我一直在使用的示例代碼:
#!/usr/bin/env python
import re
from functools import wraps
NAMES = [
{'name':'Fred Flintstone','id':1},
{'name':'Barney Rubble','id':2},
{'name':'Henry Ford','id':3},
]
def get_list(func):
@wraps(func)
def wrapper(self,*args):
res = re.match('get_(?P<list>[^_]+)(_(?P<return>.*))*',func.__name__)
if res:
list_name = res.group('list').endswith('s') and res.group('list') or (res.group('list') + 's')
if not eval("self.%s" % list_name):
exec "self._Fred__get_%s()" % list_name in globals(),locals()
return func(self,*args)
return wrapper
def search_list(func):
@wraps(func)
def wrapper(self,*args):
res = re.match('get_(?P<list>[^_]+)(_(?P<return>.*))*',func.__name__)
if res:
for x in eval('self.%ss' % res.group('list')):
if isinstance(args[0],(int,long)):
if x['id'] == args[0]:
return res.group('return') and x[res.group('return')] or x
else:
if x['name'] == args[0]:
return res.group('return') and x[res.group('return')] or x
return wrapper
class Fred(object):
def __init__(self):
self.names = []
def __get_names(self):
self.names = NAMES
@get_list
def get_names(self):
return self.names
@get_list
def get_name_names(self):
return [x['name'] for x in self.names]
@search_list
@get_list
def get_name(self,id):
pass
@search_list
def get_name_name(self,id):
pass
@search_list
def get_name_id(self,name):
pass
有你爲什麼想用裝飾來替代方法,而不是隻具有類內的通用方法,然後由專門的所謂理由方法? – poke
另外,'eval'?真的嗎? :/ – poke