1つのモジュールに次の設定があります。
class A(object):
# stuff
class B(object):
# stuff
今私がやりたいのは、の中A
に名前でクラスのインスタンスを作成することです(私はクラス名を文字列として持っています)B
。globals
関数を回避してこれを行うにはどうすればよいですか?
1つのモジュールに次の設定があります。
class A(object):
# stuff
class B(object):
# stuff
今私がやりたいのは、の中A
に名前でクラスのインスタンスを作成することです(私はクラス名を文字列として持っています)B
。globals
関数を回避してこれを行うにはどうすればよいですか?
使ってみませんA
か?それとも文字列だけ'A'
ですか?はいの場合、それglobals()['A']
が進むべき道です。代替案はそうですgetattr(sys.modules[__name__], 'A')
が、明らかglobals()
により適切です。
>>> dis.dis(lambda: getattr(sys.modules[__name__], 'Foo'))
1 0 LOAD_GLOBAL 0 (getattr)
3 LOAD_GLOBAL 1 (sys)
6 LOAD_ATTR 2 (modules)
9 LOAD_GLOBAL 3 (__name__)
12 BINARY_SUBSCR
13 LOAD_CONST 1 ('Foo')
16 CALL_FUNCTION 2
19 RETURN_VALUE
>>> dis.dis(lambda: globals()['Foo'])
1 0 LOAD_GLOBAL 0 (globals)
3 CALL_FUNCTION 0
6 LOAD_CONST 1 ('Foo')
9 BINARY_SUBSCR
10 RETURN_VALUE
>>> dis.dis(lambda: Foo)
1 0 LOAD_GLOBAL 0 (Foo)
3 RETURN_VALUE
したがって、にアクセスするためのさまざまな方法で使用される手順を見るだけで、を使用する方がFoo
、を実行globals()
するよりも高速である可能性がありますsys.modules
。
私があなたを正しく理解しているかどうか見てみましょう:
次のような設定ファイルがあります
...
connection-type: FooConnection
...
たくさんのクラスがあります
class FooConnection(Connection): ...
class BarConnection(Connection): ...
class BazConnection(Connection): ...
"FooConnection"
設定ファイルからクラス にマップしますFooConnection
。
もしそうなら、私は代わりにこれを行います:
置く
connection-type: Foo
設定ファイル、またはクラスの名前に依存しない他の人間が読める名前。
人間が読める名前から実装へのマッピングを記述します。
implementations = {
"Foo": FooConnection,
"Bar": BarConnection,
"Baz": BazConnection
}
クラスの実装方法などを変更したい場合は、このマッピングを変更できます。これにより、同義語を使用することもできます。
実装ディクショナリの設定ファイルで値を検索して、必要なクラスを取得します。
実際、あなたはすでにこれを行っています。ただ、文字列からクラスへのマッピングを明示的に書き留める代わりに、globals
辞書を使用しています。つまり、エンドユーザーが使用するクラス名を知っていると仮定します。イケてないよ。
「クラスAに名前でアクセスする」とはどういう意味かわかりませんが、実際に何をしたいかによって、通常は3つの主要なアプローチがあります。
__init__