ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 클래스 데코레이터 예제
    컴퓨터 2019. 11. 13. 01:53
    def time_this(original_function):      
        print "decorating"                      
        def new_function(*args,**kwargs):
            print "starting timer"       
            import datetime                 
            before = datetime.datetime.now()                     
            x = original_function(*args,**kwargs)                
            after = datetime.datetime.now()                      
            print "Elapsed Time = {0}".format(after-before)      
            return x                                             
        return new_function  
    
    def time_all_class_methods(Cls):
        class NewCls(object):
            def __init__(self,*args,**kwargs):
                self.oInstance = Cls(*args,**kwargs)
            def __getattribute__(self,s):
                """
                this is called whenever any attribute of a NewCls object is accessed. This function first tries to 
                get the attribute off NewCls. If it fails then it tries to fetch the attribute from self.oInstance (an
                instance of the decorated class). If it manages to fetch the attribute from self.oInstance, and 
                the attribute is an instance method then `time_this` is applied.
                """
                try:    
                    x = super(NewCls,self).__getattribute__(s)
                except AttributeError:      
                    pass
                else:
                    return x
                x = self.oInstance.__getattribute__(s)
                if type(x) == type(self.__init__): # it is an instance method
                    return time_this(x)                 # this is equivalent of just decorating the method with time_this
                else:
                    return x
        return NewCls
    
    #now lets make a dummy class to test it out on:
    
    @time_all_class_methods
    class Foo(object):
        def a(self):
            print "entering a"
            import time
            time.sleep(3)
            print "exiting a"
    
    oF = Foo()
    oF.a()

     

    output

    decorating 
    starting timer 
    entering a 
    exiting a 
    Elapsed Time = 0:00:03.000406

    s는 무엇인가?:

    __getattribute__메서드가 접근하려 하는 attribute의 namespace. 자동 호출시에는 자동으로 받는 값이다.

    __getattribute__의 이해.:

    attribute에 접근(저장된 값을 읽거나, 그냥 attribute가 언급만 되면 접근으로 간주한다. 세팅이나 게팅을 모두 포함한다.)할때 자동으로 호출되고 호출된 자리에 다른 값을 반환한다. 보통 메서드의 namespace를 반환한다.

    __getattribute__(s)는 무엇인가?:

    클래스 안에 명시적으로 정의 해놓았을 경우가 아닌, 기본적으로 가지고 있는 숨겨진 메서드이다. s parameter로 받는 attribute를 반환한다. 그냥 객체.attribute 랑 같다.

     x = 메소드 시에 메소드는 실행되는가?:

    메소드나 함수는 읽히게 되면 무조건 실행된다. 실행없이 리턴값만 얻는 방법은 없다.(데코레이터로 함수를 변경하면 가능할듯.)

    NewCls는 상속을 안하는데 왜 super는 무엇인가?:

    모든 클래스는 Object라는 base root 클래스를 상속한다. base 클래스는 자기 자식의 모든 속성과 메서드를 가지고 있다. 자식이 가진 것은 무조건 부모로 부터 상속 한 것이라는 것을 표현한 것이다. (사실 따지고 보면 자식을 만들때 역상속으로 base 클래스가 생성되는 것이지만.)

    pass를 하면 어디로 가는가?:

    그냥 아무것도 하지 않겠다는 의미이다. 다만 아무것도 써놓지 않으면 멈추므로 멈추지 말고 다음 차례를 진행하라는 의미이다. 오류가 나서 멈출 곳에 pass를 쓴다고 그냥 넘어간다는게 아니다.

     

    if 조건문에서 둘다 메소드가 자료형인데 굳이 __init__으로 물어본 이유가 무엇인가? 그냥 메소드냐고 물어보면 안되는가?:

    이건 그냥 쓸데없이 init을 사용한게 맞다.

     

    새로 형성되는 클래스(데코레이팅 되는)는 어떤 메소드와 attribute를 가지는가?:

    NewCls 클래스는 Original 클래스의 객체를 oInstance라는 attribute 변수에 저장한다. 메서드로는 __init__과 __getattribute__가 있고 Original 클래스의 메서드에 접근할 경우에만 그 메서드를 데코레이팅 하여 반환한다. NewCls는 Original의 메서드들을 바로 가진게 아니라 더 하부의 구조에 가지고 있지만 바로 접근하여도 __getattribute__에 정의도니 기능을 통해 알아서 Original로 유도된다. NewCls는 실제로 attribute가 변한게 아니라 변한거 같은 효과를 주는 것이다.

    함수데코레이터의 경우 새로운 함수가 정의되는게 확실히 보인다. 클래스는 실제적으로 새로운 클래스가 만들어지는것인지 아니면 그러한 효과만 내느것인가? 클래스가 구체적으로 무엇으로 변하였는가? 클래스의 메소드만 변한것인가?: (답변 위에 같이)

    try except if else를 하는 이유가 무엇인가? :

    클래스 modifier 가 원래 가진 함수와  Original의 함수를 구분하기 위함인데, modifier 가 가진 함수가 데코레이팅 될 경우(__init__) 생성이 방해된다. __getattribute__가 데코레이팅 될 경우 클래스 데코레이팅 자체가 엉망이 된다.

    '컴퓨터' 카테고리의 다른 글

    변수의 범위, scope, (static, 전역, 지역)  (0) 2019.12.11
    콜백함수, 람다  (0) 2019.11.17
    API, COM 모식도  (0) 2019.11.15
    super(), inheritance 실행 순서  (0) 2019.11.12
    입문자를 위한 컴퓨터 프로그래밍 기초 용어  (0) 2019.11.08

    댓글

Designed by Tistory.