masterofdestiny
masterofdestiny

Reputation: 2811

Python :TypeError: 'str' object is not callable

I am using a function to instansiate the python classes .

Hers is the class structure

from DB.models import ApiKey,ServiceProvider

class SMSMrg( object ):
    _instance = None
    class Singleton:
        def __init__(self):
            self.username = None
            self.password = None
            self.allsp = []
            self.classnames = {}
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(SMSMrg, cls).__new__(
                                cls, *args, **kwargs)
        return cls._instance

    def loadsettings(self):

        get_all_sp = ServiceProvider.objects.filter(status = False)
        for (options,obj) in enumerate(get_all_sp):
            cla = str(obj.class_Name)
            self.classnames[cla] = cla
        print self.classnames

        for (options,obj) in enumerate(get_all_sp):
            cla = str(obj.class_Name)
            class_object = self.classnames[cla](obj.userName,obj.password,obj.sendingurl)

       # self.allsp = get_all_sp 
    def send(self):
        print "+++++++++++++++++++== Global send "


if __name__ == "__main__":

    b = SMSMrg()
    b.loadsettings()

I have stored the classnames in database and I have defined each class structures on different files .

Like cla will contain a class name .

But when i am calling above function i am getting the type error .

Traceback (most recent call last):
  File "allsms.py", line 30, in <module>
    b.loadsettings()
  File "allsms.py", line 21, in loadsettings
    class_object = cla(obj.userName,obj.password,obj.sendingurl)
TypeError: 'str' object is not callable

Please tell me how can instansiate all the classes which names are present in my db .

Upvotes: 0

Views: 1939

Answers (4)

Burhan Khalid
Burhan Khalid

Reputation: 174708

Please tell me how can instansiate all the classes which names are present in my db .

Try this:

class A(object): pass
class B(object): pass

class_names = {'first': A, 'second': B}
obj = class_names['first']()
type(obj)
<class 'yourmodule.A'>

Or, if your classes are stored somewhere else, say in a module called mymodule:

import mymodule
obj = getattr(mymodule, 'A')()

Upvotes: 0

Bakuriu
Bakuriu

Reputation: 102029

As you said cla contains the name of the class, which means that you can't use it as a callable.

You can build a dict and take the class object from there:

from somemodule import SomeClass

class TheClass(object):
    def __init__(self, username, password, url):
        #do stuff

class AnOtherClass(object):
    def __init__(self, username, password, url):
        # do stuff

CLASS_NAMES_TO_CLASSES = {
    # Note: TheClass is *not* a string, is the class!!!
    'FirstName': TheClass,
    'SecondName': AnOtherClass,
    'SomeClass': SomeClass,
    }

class SMSMrg(object):
    #do stuff
    def loadsettings(self):
       get_all_sp = ServiceProvider.objects.filter(status = True)
       for obj in get_all_sp:
           SERVIVEPROVIDER = obj.class_Name
           cla = str(SERVIVEPROVIDER)
           class_object = CLASS_NAMES_TO_CLASSES[cla](obj.userName,obj.password,obj.sendingurl)

This method requires you to be able to build such a dict, so either you know ahead which classes could end up in the db or you can't use this method.

Note that CLASS_NAMES_TO_CLASSES is not a dictionary that maps strings to strings. It maps strings to class objects. If you import the class SomeClass from a module then you have to put it inside the dictionary.

An other method could be to use eval to evaluate the class name, but you should avoid this if the db contains data from users(which is not safe).

An other option that might turn out useful is to avoid saving the class names and instead use pickle to save the instances directly.

Upvotes: 0

avasal
avasal

Reputation: 14874

 # Means `cla` is pointing to a string
cla = str(SERVIVEPROVIDER)

# there is no function called `cla` now it contains a string
cla(obj.userName,obj.password,obj.sendingurl)

Upvotes: 1

root
root

Reputation: 80436

On the line cla = str(SERVIVEPROVIDER) you convert SERVIVEPROVIDER to string. And on the next line you are trying to call it, thus you get an error...

Upvotes: 1

Related Questions