2014-11-07 16 views
7

Dlaczego nie mogę utworzyć klasy "__call__ metody statycznej przy użyciu dekoratora @staticmethod?Udekoruj __call__ za pomocą @staticmethod

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

    @staticmethod 
    def __call__(): 
     return '__call__' 

print Foo.bar() 
print Foo() 

wyjścia

bar 
<__main__.Foo object at 0x7fabf93c89d0> 

ale spodziewałbym go do wyjścia

bar 
__call__ 

Odpowiedz

12

Trzeba zastąpić __call__ na metaklasą. Specjalne metody zdefiniowane w klasie są dla jej instancji, aby zmienić specjalne metody klasy, które trzeba zmienić w swojej klasie, tj. Metaclass. (Podczas rozmowy telefonicznej Foo() zwykle kolejność jest: Meta.__call__() ->Foo.__new__() ->Foo.__init__() tylko wtedy, gdy wracają normalnie)

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


class Foo(object): 
    __metaclass__ = Meta 

    @staticmethod 
    def bar(): 
     return 'bar' 

print Foo() 
#__call__ 

Gdy próbujesz zmodyfikować klasy instancji, inny sposób będzie przesłonić __new__ na samej klasy i powrócić __call__ z nim (gdy __new__ powraca coś innego niż przykład metoda __init__ nigdy nie nazywa):

class Foo(object): 

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

    @staticmethod 
    def bar(): 
     return 'bar' 

print Foo() 
#__call__ 
+0

Dzięki! To wyjaśnia to dla mnie. Co masz na myśli przez 'Meta .__ call __()' -> 'Foo .__ new __()' -> 'Foo .__ init __()'? Czy strzałki oznaczają "połączenia"? – fragapanagos

+0

@fragapanagos To kolejność, po której następuje Python, gdy tworzona jest klasa. Zobacz: http://ideone.com/4gxeiN –