2014-11-07 3 views
7

Почему я не могу сделать статический метод класса __call__ с помощью декоратора @staticmethod?decorate __call__ with @staticmethod

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

    @staticmethod 
    def __call__(): 
     return '__call__' 

print Foo.bar() 
print Foo() 

выходы

bar 
<__main__.Foo object at 0x7fabf93c89d0> 

, но я бы ожидать его выхода

bar 
__call__ 

ответ

12

Вы должны переопределить __call__ на метакласса. Специальные методы, определенные в классе, предназначены для его экземпляров, чтобы изменить специальные методы класса, необходимые для их изменения в своем классе, то есть в метаклассе. (При вызове 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 Вот такой порядок, за которым следует Python при создании экземпляра класса. См .: http://ideone.com/4gxeiN –

Смежные вопросы