0

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

クラス名をデータベースに保存し、各クラス構造を異なるファイルに定義しました。

Likecla にはクラス名が含まれます。

しかし、上記の関数を呼び出すと、タイプエラーが発生します。

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

4 に答える 4

1

行上で文字列cla = str(SERVIVEPROVIDER)に変換SERVIVEPROVIDERします。そして次の行であなたはそれを呼び出そうとしているので、あなたはエラーを受け取ります...

于 2013-02-05T06:36:35.837 に答える
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)
于 2013-02-05T06:36:42.140 に答える
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クラス名を評価するために使用することですが、データベースにユーザーからのデータが含まれている場合はこれを避ける必要があります(これは安全ではありません)。

役立つ可能性のある他のオプションは、クラス名の保存を避け、代わりpickleにインスタンスを直接保存するために使用することです。

于 2013-02-05T06:37:22.783 に答える
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')()
于 2013-02-05T06:51:19.943 に答える