将python装饰器应用于类中的方法

Jef*_*uer 15 python decorator

我有@login_testuser针对方法test_1应用的装饰器:

class TestCase(object):
    @login_testuser
    def test_1(self):
        print "test_1()"
Run Code Online (Sandbox Code Playgroud)

有没有办法可以应用test_1()前缀为"test_"的类的每个方法?

换句话说,装饰器将应用于 下面的test_1,test_2方法,但不适用于setUp.

class TestCase(object):
    def setUp(self):
        pass

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

    def test_2(self):
        print "test_2()"
Run Code Online (Sandbox Code Playgroud)

Ale*_*lli 21

在Python 2.6中,类装饰器绝对是最佳选择.例如,这是一个非常普遍的这类任务:

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
Run Code Online (Sandbox Code Playgroud)

而现在,只是

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

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

    def test_2(self):
        print "test_2()"
Run Code Online (Sandbox Code Playgroud)

会得到你想要的东西.在Python 2.5或更糟的情况下,@decallmethods语法不适用于类装饰,但是在完全相同的代码中,您可以在语句结束后立即将其替换为以下class TestCase语句:

TestCase = decallmethods(login_testuser)(TestCase)
Run Code Online (Sandbox Code Playgroud)


tru*_*ppo 5

当然。迭代类的所有属性。检查每个方法是否为方法以及名称是否以“test_”开头。然后用装饰器返回的函数替换它

就像是:

from inspect import ismethod, getmembers
for name, obj in getmembers(TestCase, ismethod):
   if name.startswith("test_"):
       setattr(TestCase, name, login_testuser(obj))
Run Code Online (Sandbox Code Playgroud)

  • 我什至会把它放在一个类装饰器中。 (4认同)