简体   繁体   English

Python:TypeError:'str'对象不可调用

[英]Python :TypeError: 'str' object is not callable

I am using a function to instansiate the python classes . 我正在使用一个函数来实现python类。

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 . like cla将包含一个类名。

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 . 请告诉我如何实现我的数据库中存在的所有类的名称。

On the line cla = str(SERVIVEPROVIDER) you convert SERVIVEPROVIDER to string. cla = str(SERVIVEPROVIDER)您将SERVIVEPROVIDER转换为字符串。 And on the next line you are trying to call it, thus you get an error... 在下一行你试图调用它,因此你得到一个错误......

 # 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)

As you said cla contains the name of the class, which means that you can't use it as a callable. 如你所说cla包含cla的名称,这意味着你不能将它用作可调用的。

You can build a dict and take the class object from there: 你可以构建一个dict并从那里获取类对象:

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. 这个方法要求你能够构建这样一个dict ,所以要么你知道哪些类可以在db中结束,要么你不能使用这个方法。

Note that CLASS_NAMES_TO_CLASSES is not a dictionary that maps strings to strings. 请注意, CLASS_NAMES_TO_CLASSES 不是将字符串映射到字符串的字典。 It maps strings to class objects. 它将字符串映射到类对象。 If you import the class SomeClass from a module then you have to put it inside the dictionary. 如果从模块导入类SomeClass ,则必须将其放在字典中。

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). 另一种方法可能是使用eval来评估类名,但如果db包含来自用户的数据(这是不安全的),则应该避免这种情况。

An other option that might turn out useful is to avoid saving the class names and instead use pickle to save the instances directly. 另一个可能有用的选项是避免保存类名,而是使用pickle直接保存实例。

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 : 或者,如果您的类存储在其他地方,请在名为mymodule的模块中说:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM