Search code examples
pythonclassmethodscallattributeerror

Python says my class has no __call__ method


I'm completely stuck. Thought I've already understood classes, guess I was wrong :/ Anyway, my code looks like this:

class LinearRegression:

def __init__(self, x, y, full = 0):
    self.full = full
    self.x = x
    self.y = y

def __call__(self):
    squared_sum_x = (sum(self.x))**2 
    n = len(self.x)
    xx = sum([item**2 for item in self.x])
    xy = sum([xi*yi for xi, yi in zip(self.x,self.y)])
    a = 1.0*((n*xy -(sum(self.y)*sum(self.x)))/(n*xx - squared_sum_x))
    b = (sum(self.y) - a*sum(self.x))/n
    if self.full == 0:
        return (a,b)
    elif self.full == 1:
        squared_sum_y = (sum(self.y))**2
        yy = sum([item**2 for item in self.y])
        R = float((n*xy -(sum(self.y)*sum(self.x)))/(((n*xx - squared_sum_x)*(n*yy - squared_sum_y))**0.5))
        S_a = (1/(n-2))*((yy-(a*xy)-(b*sum(self.y)))/(xx-(n*xx)))
        S_b = S_a * (n*xx)
        return (a, b, R, S_a, S_b)
    else:
        return "full parameter must be 0, 1 or empty"

lr = LinearRegression(range(10),range(10,30,2),0)
lr()

And I am getting following error:

AttributeError: LinearRegression instance has no __call__ method

Question is: why ? Because I've spent hours analysing this bit of code and have absolutely no idea what's wrong...


Solution

  • I think that the issue is in your indentation. You're not actually including those methods in your class, since your indentation is placing them "outside". Try this instead:

    class LinearRegression:
    
        def __init__(self, x, y, full = 0):
            self.full = full
            self.x = x
            self.y = y
    
        def __call__(self):
            squared_sum_x = (sum(self.x))**2 
            n = len(self.x)
            xx = sum([item**2 for item in self.x])
            xy = sum([xi*yi for xi, yi in zip(self.x,self.y)])
            a = 1.0*((n*xy -(sum(self.y)*sum(self.x)))/(n*xx - squared_sum_x))
            b = (sum(self.y) - a*sum(self.x))/n
            if self.full == 0:
                return (a,b)
            elif self.full == 1:
                squared_sum_y = (sum(self.y))**2
                yy = sum([item**2 for item in self.y])
                R = float((n*xy -(sum(self.y)*sum(self.x)))/(((n*xx - squared_sum_x)*(n*yy - squared_sum_y))**0.5))
                S_a = (1/(n-2))*((yy-(a*xy)-(b*sum(self.y)))/(xx-(n*xx)))
                S_b = S_a * (n*xx)
                return (a, b, R, S_a, S_b)
            else:
                return "full parameter must be 0, 1 or empty"
    

    This way the methods will be "inside" your class, as opposed to being independently defined functions.