我是第一次接触装饰器,我创建了一个装饰器类来过滤目标函数的结果,它默认返回一个特定的序列:
class Filter(object):
def __init__(self, id=None):
self.id = id
def __call__(self, func):
def wrapper(*args):
entity_ids = func(*args)
result = {}
for k, v in entity_ids.items():
if self.id:
if '_' + str(self.id) in k:
result.update({k: v})
return result
return wrapper
我在其他一些类方法中使用装饰器,如下所示:
class SomeClass(object):
@Filter(id=None)
def get_ids(*args):
return result_sequence
如何在调用类方法时为装饰器定义参数:
>>>sc = SomeClass()
>>>sc.get_ids(*args) # I want to pass the id kwarg for Filter here
提前致谢
最佳答案
您在类定义中应用了 Filter
装饰器;您在 id
参数中传递的是 :
@Filter(id=None)
如果 id
应该是别的东西,你需要在那里传递那个值。
Filter()
对象在 @Filter(id=None)
行中创建,然后被调用。您还可以重写代码以读取:
class SomeClass(object):
def get_ids(*args):
return result_sequence
get_ids = Filter(id=None)(get_ids)
因为这就是 Python 在处理装饰器时所做的。
它是 Filter.__call__()
方法的返回值,它取代了 get_ids
,您不能再为 Filter()
对象。 SomeClass.get_ids()
现在是装饰器返回的嵌套 wrapper()
函数。
如果您想在调用装饰方法时指定 id
,您需要更改 wrapper()
签名以接受(可选的)额外的 id
参数。因为您已经支持 *args
,所以您唯一的选择是添加一个 **kwargs
包罗万象的参数以支持可选的关键字参数:
def wrapper(*args, **kwargs):
id = kwargs.get('id', self.id)
entity_ids = func(*args)
result = {}
for k, v in entity_ids.items():
if id:
if '_' + str(id) in k:
result.update({k: v})
return result
这里,不是直接使用 self.id
,而是包装器的 id
关键字参数覆盖装饰器类上设置的 id
值:
sc.get_ids(*args, id='foo')
您可能还想将任何关键字参数传递给包装函数;在那种情况下,我会使用:
def wrapper(*args, **kwargs):
id = kwargs.pop('id', self.id)
entity_ids = func(*args, **kwargs)
result = {}
for k, v in entity_ids.items():
if id:
if '_' + str(id) in k:
result.update({k: v})
return result
在这里,id
关键字参数在将剩余的关键字参数传递给包装函数之前被删除。
关于python - 调用装饰函数时将参数传递给装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19446529/