2014-11-07 2 views
7

@staticmethod 데코레이터를 사용하여 클래스 '__call__ 메소드를 정적으로 만들 수없는 이유는 무엇입니까?@staticmethod로 __call__을 장식하기

class Foo(object): 
    @staticmethod 
    def bar(): 
     return 'bar' 

    @staticmethod 
    def __call__(): 
     return '__call__' 

print Foo.bar() 
print Foo() 

출력

bar 
<__main__.Foo object at 0x7fabf93c89d0> 

하지만 출력

당신은 메타 클래스에 __call__를 오버라이드 (override) 할 필요가
bar 
__call__ 

답변

12

에 기대. 클래스에서 정의 된 특별한 메소드는 클래스의 특별한 메소드 (예 : 메타 클래스)를 변경해야하는 인스턴스에 대한 것입니다. (당신이 Foo()를 호출 할 때 보통 순서는 다음과 같습니다 Meta.__call__() ->Foo.__new__() ->Foo.__init__(), 그들은 일반적으로 반환하는 경우에만)이 클래스의 인스턴스를 수정하려는으로

class Meta(type): 
    @staticmethod 
    def __call__(): 
     return '__call__' 


class Foo(object): 
    __metaclass__ = Meta 

    @staticmethod 
    def bar(): 
     return 'bar' 

print Foo() 
#__call__ 

, 또 다른 방법이 될 것입니다 클래스 자체에 __new__을 무시하고 그것에서 __call__을 반환 (인스턴스 이외의 __new__ 반환 뭔가가 __init__ 메서드가 호출되지 않습니다 경우) :

class Foo(object): 

    def __new__(*args): 
     #ignore the args 
     return '__call__' 

    @staticmethod 
    def bar(): 
     return 'bar' 

print Foo() 
#__call__ 
+0

감사합니다! 그것은 나를 위해 그것을 깨끗하게한다. 'Meta .__ call __()'->'Foo .__ new __()'->'Foo .__ init __()'의 의미는 무엇입니까? 화살표는 "전화"를 의미합니까? – fragapanagos

+0

@fragapanagos 클래스가 인스턴스화 될 때 파이썬이 따르는 순서입니다. 참조 : http://ideone.com/4gxeiN –

관련 문제