Pythonで実行時にクラスを動的に作成したい。
たとえば、次のコードを複製します。
>>> class RefObj(object):
... def __init__(self, ParentClassName):
... print "Created RefObj with ties to %s" % ParentClassName
... class Foo1(object):
... ref_obj = RefObj("Foo1")
... class Foo2(object):
... ref_obj = RefObj("Foo2")
...
Created RefObj with ties to Foo1
Created RefObj with ties to Foo2
>>>
...しかし、Foo1、Foo2、Foo クラスを動的に作成したい (つまり、最初のパスのコンパイルではなく実行中に)。
これを実現する 1 つの方法は、次type()
のように を使用することです。
>>> class RefObj(object):
... def __init__(self, ParentClassName):
... print "Created RefObj with ties to %s" % ParentClassName
... def make_foo_class(index):
... name = "Foo%s" % index
... return type(name, (object, ), dict(ref_obj = RefObj(name)))
...
>>> Foo1 = make_foo_class(1)
Created RefObj with ties to Foo1
>>> Foo2 = make_foo_class(2)
Created RefObj with ties to Foo2
>>> type(Foo1()), type(Foo2())
(<class 'Foo1'>, <class 'Foo2'>)
exec
次のように、でそれを達成することもできます。
>>> class RefObj(object):
... def __init__(self, ParentClassName):
... print "Created RefObj with ties to %s" % ParentClassName
... def make_foo_object(index):
... class_template = """class Foo%(index)d(object):
... ref_obj = RefObj("Foo%(index)d")
... """ % dict(index = index)
... global RefObj
... namespace = dict(RefObj = RefObj)
... exec class_template in namespace
... return namespace["Foo%d" % index]
...
>>> Foo1 = make_foo_object(1)
Created RefObj with ties to Foo1
>>> Foo2 = make_foo_object(2)
Created RefObj with ties to Foo2
>>> type(Foo1()), type(Foo2())
(<class 'Foo1'>, <class 'Foo2'>)
の使用はexec
私にはうまくいきません(この質問を読んだ多くの人にはそうではないと思います)が、exec
まさにpythonのcollections.namedtuple()
クラスがどのように実装されているかです(この行を参照)。また、クラスの作成者 (Raymond Hettinger) による、exec
hereの使用に対する弁護も非常に関連性があります。この弁護では、「名前付きタプルの重要な機能は、手書きのクラスとまったく同等である」と述べtype()
られていexec
ます。
違いはありますか?exec
vsをtype()
使用する理由
答えは、両方の方法が同じであり、namedtuple
実装に多くの名前付きタプル変数が散りばめられているだけであり、すべてのメソッドのクロージャーを動的に生成してこれを行うと、コードが扱いにくくなる可能性があると思いますが、知りたいですこれにさらに何かがある場合。
に対する私の不快感についてはexec
、信頼できない関係者が悪意のあるコードを挿入する方法がまったくない場合は、それで問題ないことを認識しています...それが私を緊張させるだけです.