What Does "Typeerror 'Xxx' Object Is Not Callable" Means

What does TypeError 'xxx' object is not callable means?

That error occurs when you try to call, with (), an object that is not callable.

A callable object can be a function or a class (that implements __call__ method). According to Python Docs:

object.__call__(self[, args...]): Called when the instance is “called” as a function

For example:

x = 1
print x()

x is not a callable object, but you are trying to call it as if it were it. This example produces the error:

TypeError: 'int' object is not callable

For better understaing of what is a callable object read this answer in another SO post.

JSON serialized object gives error with multiprocessing calls - TypeError: XXX objects not callable error

The problem is you are in a "pickle". Forgive the pun -- you have a pickle problem. When you are doing multiprocessing, the arguments to your worker functions/methods are pickled. Usually, the defaults used to serialize and de-serialize states are OK, but not in your case. See Pickling Class Instances. The default save and load operations for serializing and de-serializing an object are:

def save(obj):
return (obj.__class__, obj.__dict__)

def load(cls, attributes):
obj = cls.__new__(cls)
obj.__dict__.update(attributes)
return obj

Note that when de-serializing the object the object's __init__ method is not called but its __new__ method is, and therein lies the problem. I had to modify your __new__ method of class JSONDict to try to recognize that it was being called by de-serialization and therefore '__name__' may not be present among the keyword arguments and then had to add to that class customized __getstate__ and __setstate__ methods to override the default way it saves and restores the object's attributes (method __init__ remains unmodified):

class JSONDict(dict):
"Allows dotted access"
def __new__(cls,*args,**kwds):
self = dict.__new__(cls,*args,**kwds)
if kwds and '__name__' in kwds:
__name__ = kwds.pop('__name__')
self.__name__ = __name__
return self

def __init__(self,*args,**kwds):
kwds.pop('__name__','')
dict.__init__(self,*args,**kwds)

def __getstate__(self):
return self.__dict__

def __setstate__(self, d):
self.__dict__ = d

""" The other methods remain unmodified """

Prints:

test_data
john
mnl
john
test_data
michal
david
test_data
test_data

Update

I was scratching my head figuring out why it should be necessary to provide the __getstate__ and __setstate__ pickle methods since what they are doing should be the default action anyway. If you modify the program just to test the pickling without even running the Pool methods by inserting the following line:

json_obj = condJSONSafe(data)
# insert this line:
import pickle; print(pickle.dumps(json_obj)); sys.exit(0)

It prints:

Traceback (most recent call last):
File "test.py", line 205, in <module>
import pickle; print('pickle'); print(pickle.dumps(json_obj)); sys.exit(0)
TypeError: 'JSONStrSafe' object is not callable

After adding a print statement in the right place, it became clear that the problem was in the __getattr__ method of class JSONDictSafe. When pickle checks to see if the class implements methods __getstate__ and __setstate__, when there are no implementations __getattr__ is ultimately called and returns as the default value for these attributes a JSONStrSafe instance. So instead of providing these attributes by defining these methods as I have done, one can alternatively add a simple check as follows:

class JSONDictSafe(JSONDict):
"Allows dotted access"
def __getattr__(self, attr, default=None):
if attr in ('__getstate__', '__setstate__'):
raise AttributeError(f'Missing attribute: {attr}')
""" rest of the method is unmodified """

Pylint: self.xxx is not callable

Try putting the function in the dictionary literal instead of assigning it later.

class Net(torch.nn.Module):
self.architecture = {"backbone": model, "bottleneck": None, "head": None}


Related Topics



Leave a reply



Submit