Python:类型错误:'str'对象不可调用
我正在使用一个函数来实例化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
来保存实例。