4

I have the following code

import numpy as np

class Estimator(object):
    name = None

    def __init__(self):
        self.__call__ = self._call

class Mean(Estimator):
    name = 'mean'

    def _call(self, data):
        return np.mean(data)

data = np.arange(10)

now, why I can't use the second class as a functor as the first?

It seems to work:

M = Mean()
print M.__call__(data)  # -> 4.5

M has the method __call__:

print '__call__' in dir(M)  # -> True

but it doesn't work

print M(data)

I get:

TypeError: 'Mean' object is not callable
user2864740
  • 60,010
  • 15
  • 145
  • 220
Ruggero Turra
  • 16,929
  • 16
  • 85
  • 141

1 Answers1

6

As Ashwini says, "Special methods are looked up in class not instances".

So the following would work as you expect (although I can't imagine why you would want to):

class Estimator(object):
    name = None

    def __init__(self):
        self.__class__.__call__ = self.__class__._call

class Mean(Estimator):
    name = 'mean'

    def _call(self, data):
        return np.mean(data)
isedev
  • 18,848
  • 3
  • 60
  • 59
  • Setting the `__call__` method class-wide to the new instance's `_call` means multiple estimators of the same class won't work right. – user2357112 Mar 13 '14 at 21:05
  • @user2357112 explain that... in the given example, it's setting `Mean.__call__` to `Mean._call`. What's it got to do with the instance? – isedev Mar 13 '14 at 21:10
  • No, it's setting `Mean.__call__` to `self._call`, a bound method. – user2357112 Mar 13 '14 at 21:10
  • @user2357112 ok, I see your point... updated to act upon the class. – isedev Mar 13 '14 at 21:13
  • 1
    @isedev: I need it because I want to resolve which function to call with `__call__` when building the class. In my real code I have two `_call` functions and the base class decides which to use depending on an argument of `__init__` – Ruggero Turra Mar 13 '14 at 22:28