2017-12-22 34 views
1

メソッドに供給される文字列からクラスを動的にインスタンス化しようとしています。locateを使ってクラスを動的にインスタンス化

from pydoc import locate 
name = "folder.subfolder.classname" 
my_class = locate(name) 
instance = my_class() 

エラーが発生し、これを行う:

TypeError: 'module' object is not callable 

私の質問は:どのように私はdinamically私が呼び出す必要がどのクラスを知ることができますか?値をハードコードしてmy_class.classname()をインスタンス化することはできますが、最後の部分をハードコードではなく動的にしたいとします。どうやってやるの?

答えて

2

編集2:

このソリューションは、ユーザが提供するモジュールで利用可能なすべてのクラスを集め、そして、単に最初のクラスをインスタンス化します。

import inspect 
from pydoc import locate 
name = "folder.subfolder.classname" 
my_module = locate(name) 

all_classes = inspect.getmembers(my_module, inspect.isclass) 
if len(all_classes) > 0: 
    instance = all_classes[0][1]() 

編集:私は次のコードは、あなたのユースケースのために働くだろうと考えているコメントから収集

from pydoc import locate 
name = "folder.subfolder.classname" 
my_module = locate(name) 
class_name = name.rsplit('.')[-1] 
my_class = getattr(my_module, class_name) 
instance = my_class() 

あなたはどのようなモジュールへと少し混乱しているようですん私たちの誤ったコミュニケーションの原因となっています。 class.pyはクラスを指すのではなく、モジュールを指します。そのモジュール(class.pyファイル)には複数のクラスがあります。上記の答えのために、私はあなたのclass.pyファイルに、ファイルと同じ名前のクラスがあると仮定します。

オリジナル回答:あなたのエラーが示すようにまあ

、あなたmy_class変数は、実際にモジュールオブジェクトです。あなたが提供する名前は実際にあなたのクラスを指し示すのではなく、そのクラスを含むモジュールに指し示します。

あなたが行うことができ、文字列によって、モジュールオブジェクトからクラスを取得するには、次の

my_class = getattr(module, class_name) 

をして、あなたのコード例のように、あなたがこのようにそれをインスタンス化することができます:それはすべてを持って来るために

instance = my_class() 

一緒に:

+0

これはオプションではありません。変数class_nameはどこにありますか? – BlunT

+0

あなたが呼んでいるこのロケート機能の詳細を教えてください。あなたの問題は、単にモジュール名を忘れてしまったように思えるからです。 '' folder.subfolder.classname ""を使う代わりに '' folder.subfolder.modulename.classname "'を試してみるべきです。モジュール名は '.py'のないpythonファイルの名前です。 –

+0

locateはpydocからです。質問に追加しました。構造体は "folder \ subfolder \ class.py"であり、 "folder.subfolder.class"でクラスにアクセスしようとしています。 – BlunT

関連する問題