【问题标题】:How Can I Pass args in Class Decorators in Python?如何在 Python 的类装饰器中传递参数?
【发布时间】:2015-10-27 01:55:55
【问题描述】:

我在 Python 中使用此代码将装饰器应用于类的所有方法:

import inspect

def decallmethods(decorator, prefix='test_'):
  def dectheclass(cls):
    for name, m in inspect.getmembers(cls, inspect.ismethod):
      if name.startswith(prefix):
        setattr(cls, name, decorator(m))
    return cls
  return dectheclass


@decallmethods(login_testuser)
class TestCase(object):
    def setUp(self):
        pass

    def test_1(self):
        print "test_1()"

    def test_2(self):
        print "test_2()"

这很好用。但是,我想将一些kwargs 传递给我想申请的装饰器。

所以,我想要类似的东西:

@decallmethods(login_testuser, data="TEST") on class

它应用于方法的装饰器变为:

@login_testuser(data="TEST")

【问题讨论】:

  • 为什么不直接用setUp方法登录测试用户(并使用unittest)?

标签: python decorator


【解决方案1】:

您构造它的方式意味着您的decorator 参数decallmethods 成为一个装饰器工厂(构造器),就像decallmethods 返回一个类装饰器一样。如果你明白了,你只需要改变调用方式

setattr(cls, name, decorator(m))

setattr(cls, name, decorator(data="TEST")(m))

对于静态实现。要使这种动态化,您还需要重新定义 decallmethods 以接受 data 参数

def decallmethods(decorator, prefix='test_', data='TEST'):
...
        setattr(cls, name, decorator(data=data)(m))

(另外,回想一下the time,当我向您指出装饰器只是接受一个函数返回一个新函数的函数时,在您的情况下,调用是test_method = login_testuser(data="TEST")(test_method),当它以这种方式放置时,繁殖是微不足道的。)

当然,这假定函数 decorator 将能够使用 data 参数,并且如果您传入不是装饰器工厂的装饰器或不期望此参数的函数,则会发生异常。

【讨论】:

  • 感谢 agian 帮助我 :)。很抱歉造成混淆,但这段代码只是我从某处复制的示例,以显示我想要实现的目标。但我的代码不同。它与单元测试无关。这只是显示我正在寻找的示例代码
  • 啊,不客气。不过,请注意我在答案中提到的警告和注意事项,如果不小心,它们可能会凶猛地咬人。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-19
  • 1970-01-01
  • 2018-12-04
  • 2018-08-24
  • 2018-08-01
  • 2020-04-13
相关资源
最近更新 更多