Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

decorate __call__ with @staticmethod

Why can't I make a class' __call__ method static using the @staticmethod decorator?

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

    @staticmethod
    def __call__():
        return '__call__'

print Foo.bar()
print Foo()

outputs

bar
<__main__.Foo object at 0x7fabf93c89d0>

but I would expect it to output

bar
__call__
like image 958
fragapanagos Avatar asked Nov 07 '14 03:11

fragapanagos


1 Answers

You need to override __call__ on the metaclass. The special methods defined in a class are for its instances, to change a class's special methods you need to change them in its class, i.e metaclass. (When you call Foo() usually the order is: Meta.__call__() --> Foo.__new__() --> Foo.__init__(), only if they return normally)

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


class Foo(object):
    __metaclass__ = Meta

    @staticmethod
    def bar():
        return 'bar'

print Foo()
#__call__

As you're trying to modify class instantiation, another way will be to override __new__ on the class itself and return __call__ from it(when __new__ returns something other than an instance the __init__ method is never called):

class Foo(object):

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

    @staticmethod
    def bar():
        return 'bar'

print Foo()
#__call__
like image 54
Ashwini Chaudhary Avatar answered Oct 20 '22 23:10

Ashwini Chaudhary