Pythonでクラス名に変数を使用していますか?
-
03-07-2019 - |
質問
Pythonでオブジェクトと関数名に変数を使用する方法を知りたい。 PHPでは、これを行うことができます。
$className = "MyClass";
$newObject = new $className();
このようなことをPythonでどのように行うのですか?または、私はPythonとの根本的な違いをまったく認識していないのですか?もしそうなら、それは何ですか?
解決
Pythonでは、
className = MyClass
newObject = className()
最初の行は、変数 className
が MyClass
と同じものを参照するようにします。次に、次の行は className
変数を介して MyClass
コンストラクターを呼び出します。
具体例として:
>>> className = list
>>> newObject = className()
>>> newObject
[]
(Pythonでは、 list
は list
クラスのコンストラクタです。)
違いは、PHPでは文字列として参照するクラスの名前を表すのに対して、Pythonでは同じクラスを直接参照できることです。文字列を使用する必要がある場合(たとえば、クラスの名前が動的に作成される場合)、他の手法を使用する必要があります。
他のヒント
some_moduleに" class_name"という名前のクラスがあると仮定すると:
import some_module
klass = getattr(some_module, "class_name")
some_object = klass()
ここで注意する必要があることに注意する必要があります。文字列がユーザーから来た場合、文字列をコードに変換することは危険です。したがって、この状況ではセキュリティに留意する必要があります。 :)
もう1つの方法(まだ" class_name"を使用していると仮定):
class_lookup = { 'class_name' : class_name }
some_object = class_lookup['class_name']() #call the object once we've pulled it out of the dict
後者の方法はおそらく最も安全な方法であるため、可能な限り使用する必要があります。
Pythonで動的クラス(名前が変数であるクラス)を作成する必要がある場合は、3つのパラメーターを取るtype()を使用できます。 名前、ベース、attrs
>>> class_name = 'MyClass'
>>> klass = type(class_name, (object,), {'msg': 'foobarbaz'})
<class '__main__.MyClass'>
>>> inst = klass()
>>> inst.msg
foobarbaz
- ただし、これはオブジェクトを「インスタンス化」しないことに注意してください(つまり、コンストラクターなどを呼び出しません。同じ名前のnew(!)クラスを作成します。
これがある場合:
class MyClass:
def __init__(self):
print "MyClass"
その後、通常これを行います:
>>> x = MyClass()
MyClass
しかし、あなたはこれを行うこともできます、それはあなたが尋ねていると思うことです:
>>> a = "MyClass"
>>> y = eval(a)()
MyClass
しかし、&quot; eval()&quot;を使用する文字列をどこで取得するかに非常に注意してください。 on-ユーザーからのものである場合、本質的に巨大なセキュリティホールを作成しています。
更新:coleiferの答えに示されている type()
を使用することは、このソリューションよりもはるかに優れています。