Python:类型错误:'str'对象不可调用

0 投票
4 回答
1916 浏览
提问于 2025-04-17 14:47

我正在使用一个函数来实例化Python类。

这是类的结构:

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

我把类名存储在数据库里,并且在不同的文件中定义了每个类的结构。

比如说,cla会包含一个类名。

但是当我调用上面的函数时,出现了类型错误。

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

请告诉我如何实例化我数据库中存在的所有类。

4 个回答

1

在这一行 cla = str(SERVIVEPROVIDER) 中,你把 SERVIVEPROVIDER 转换成了字符串。然后在下一行你试图去调用它,所以就出现了错误...

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

当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。

0

正如你所说,cla 是类的名字,这意味着你不能直接把它当作可调用的对象。

你可以建立一个 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)

这种方法要求你能够构建这样的 dict,所以你要么提前知道哪些类可能会出现在数据库里,要么就不能使用这种方法。

需要注意的是,CLASS_NAMES_TO_CLASSES 不是一个将字符串映射到字符串的字典。它是将字符串映射到类对象。如果你从某个模块导入了类 SomeClass,那么你必须把它放进字典里。

另一种方法是使用 eval 来评估类名,但如果数据库里有用户的数据,就应该避免这样做,因为这不安全。

还有一个可能有用的选项是避免保存类名,而是直接使用 pickle 来保存实例。

撰写回答