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

时间:2013-02-05 06:34:02

标签: python django

我正在使用一个函数来实现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 个答案:

答案 0 :(得分:1)

cla = str(SERVIVEPROVIDER)行上,您将SERVIVEPROVIDER转换为字符串。在下一行你试图调用它,因此你得到一个错误......

答案 1 :(得分: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)

答案 2 :(得分: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,所以要么你知道哪些类可以在db中结束,要么你不能使用这个方法。

请注意,CLASS_NAMES_TO_CLASSES 是将字符串映射到字符串的字典。它将字符串映射到类对象。如果从模块导入类SomeClass,则必须将其放在字典中。

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

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

答案 3 :(得分:0)

  

请告诉我如何实现所有名称的类   出现在我的数据库中。

试试这个:

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

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

或者,如果您的课程存储在其他地方,请在名为mymodule

的模块中说明
import mymodule
obj = getattr(mymodule, 'A')()