3

1つのモジュールに次の設定があります。

class A(object):
    # stuff

class B(object):
    # stuff

今私がやりたいのは、の中Aに名前でクラスのインスタンスを作成することです(私はクラス名を文字列として持っています)Bglobals関数を回避してこれを行うにはどうすればよいですか?

4

3 に答える 3

7

使ってみません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

于 2012-05-19T12:05:14.987 に答える
3

私があなたを正しく理解しているかどうか見てみましょう:

  • 次のような設定ファイルがあります

    ...
    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辞書を使用しています。つまり、エンドユーザーが使用するクラス名を知っていると仮定します。イケてないよ。

于 2012-05-19T12:42:53.003 に答える
2

「クラスAに名前でアクセスする」とはどういう意味かわかりませんが、実際に何をしたいかによって、通常は3つの主要なアプローチがあります。

  1. クラスB内にクラスAのインスタンスを作成します__init__
  2. クラスBのクラスAから継承します
  3. @ThiefMasterが投稿したもの。
于 2012-05-19T12:07:13.930 に答える