gratsby
gratsby

Reputation: 3137

"List object is not callable" Python Error

I'm working on a Python Image Library project for fun. I cannot however, figure out why I keep getting a "list not callable" error for this code:

def __computeTopColors(self):
    temp1, temp2, temp3, temp4 = [], [], [], []

    max = (0,0,0)
    for v in self.PixelVals: 
        if (v[0] > max[0]) and (v[1] > max[1]) and (v[2] > max[2]):
            max = v

    min = (1000,1000,1000)
    for v in self.PixelVals:
        if (v[0] < min[0]) and (v[1] < min[1]) and (v[2] < min[2]):
            min = v

    for pval in self.PixelVals:
        if (min[0] <= pval[0] <= int(((max[0])/2))) and (min[1] <= pval[1] <= int(((max[1])/2))):
            temp1.append(pval) 

    return temp1

def temp(self): 
    print self.temp

Note: This is actually an excerpt from a class, but I don't think that's particularly relevant. self.PixelVals is a list tuples of the form (R,G,B). self.temp is a temporary method I'm using to test the __computeTopColors method; I set self.temp equal to self.__computeTopColors in __init__.

The Traceback :

Traceback (most recent call last):
  File "fiveColors.py", line 39, in <module>
    a.temp()

Line 39 is the last line in my code block.

Upvotes: 3

Views: 2672

Answers (2)

abarnert
abarnert

Reputation: 365597

I pasted that code into a file, and add the following:

>>> class Foo(object):
...    pass
>>> a = Foo()
>>> a.PixelVals = [(1,2,3),(4,5,6)]
>>> __computeTopColors(a)
[(1, 2, 3)]

So there is nothing wrong with this code.

Scratch that—there are stylistic problems, just none of them break the code. For example:

  • You should never give your variables names like min and max that are the same as names of built-in functions.
  • Don't put in tons of extra parens that have no function except to make things harder to read—int(((max[1])/2)) is obviously exactly equivalent to int(b[1]/2), but it takes a few seconds and a bit of thought to see what you're doing this way, and even longer to verify that you did it correctly (which is always a problem, but especially so when you're asking other people to look at your code and guess what might be wrong with it).
  • You should name variables like PixelVals in lowercase instead of CamelCase, etc.

So obviously, whatever's wrong is in some other part of your code that you didn't show us.

You added the last line of the traceback, and said that it was from "the last line in my code block". The last line is this:

print self.temp

The error complains about this:

a.temp()

Clearly, the code you showed us is not the code you're running. But I can make a guess about the problem from this:

That a is probably a class variable or global variable that holds a list. You're trying to call it as a function. So Python, quite sensibly, tells you that list objects are not callable.

Or, here's another guess:

I set self.temp equal to self.__computeTopColors

Well, that's going to replace the method temp with a different variable. As written, it would actually replace the method temp with the bound method __computeTopColors, which couldn't could the problem you're seeing (although it's a very strange and bad thing to do). But maybe this isn't actually true, and you actually set self.temp equal to self.__computeTopColors()—the result of calling that bound method. Which is probably a list. So now, some other code that you haven't shown us tries to call the temp method by doing a.temp(), and because you've replaced the temp method with a list instead of something callable, that raises the same error.

In fact, even if you didn't replace the temp method, it's not exactly useful as defined:

def temp(self): 
    print self.temp

There is no way this could print anything other than your implementation's representation of the bound method temp (e.g., <bound method Foo.temp of <__main__.Foo object at 0x106d0f2d0>>), which can't possibly be useful to you in any way.

Whether it's the first problem, the second, or something entirely different, this all points to the same larger issue: Don't give arbitrary, meaningless names to variables—and, if you do, be very careful not to reuse the same names to mean different things in different places. If you're lucky, you'll confuse Python and get an error. If you're unlucky, you'll only confuse yourself and other readers of your code.

Upvotes: 2

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798456

You've shadowed int with a list somewhere. Stop doing that. And stop shadowing min() and max() while you're at it.

Upvotes: 6

Related Questions