2010-02-10 3 views
12

메소드 에 대해 @login_testuser가 적용되었습니다. test_1 :클래스의 메소드에 파이썬 장식자를 적용하기

class TestCase(object): 
    @login_testuser 
    def test_1(self): 
     print "test_1()" 

"test_"접두어가 붙은 모든 클래스 메소드에 @login_testuser을 적용 할 수있는 방법이 있습니까?

즉, 장식자는 아래 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()" 

답변

18

파이썬 2.6에서는 class decorator이 가장 좋은 방법입니다. 단지

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

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

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

은 당신이 원하는 무엇을 얻을 것이다, 지금

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 

과 : 예를 들어, 여기에 작업의 이러한 종류의 매우 일반적인 일입니다. 파이썬 2.5 또는 더 나쁜에서 @decallmethods 구문은 클래스 장식 작동하지 않지만, 그렇지 않으면 정확히 같은 코드는 바로 class TestCase 문이 끝난 후 다음 문으로 대체 할 수 있습니다

TestCase = decallmethods(login_testuser)(TestCase) 
3

확실히. 클래스의 모든 속성을 반복합니다. 각각의 메소드를 확인하고 이름이 "test_"로 시작하는지 확인하십시오.

from inspect import ismethod, getmembers 
for name, obj in getmembers(TestCase, ismethod): 
    if name.startswith("test_"): 
     setattr(TestCase, name, login_testuser(obj)) 
+3

I 심지어 그것을 클래스 데코레이터에 넣을 수도 있습니다. – Wim

0

예, 할 수 있습니다 돌이 클래스의 dir/__dict__ 또는 속성으로 시작하는 경우 식별, 그렇게 메타 클래스가 "그런 다음 당신의 장식에서 반환 된 기능

뭔가 등으로 교체 테스트". 그러나 이렇게하면 데코레이터를 명시 적으로 작성하는 것보다 덜 명확하고 명확한 코드가 작성됩니다.

3

login_testuser의 코드를 setUp에 넣는 것이 좋을까요? 그것이 setUp의 목적입니다. 모든 테스트 방법 이전에 실행됩니다.

+0

제안에 감사드립니다. 그러나 특정 접두사가있는 메소드에만 데코레이터를 적용하고 setUp을 모든 메소드에 적용합니다. –

+2

아마 그 방법을 그들 자신의 클래스로 분리 할 것인가? 마술 검사와 방법의 증가는 신비한 유지 보수의 두통처럼 들립니다. –

관련 문제