3

私はプログラミングが初めてなので、ばかげた質問をして私を殺さないでください。私はPythonでそのすべてのクラスビジネスを理解しようとしてきましたが、グーグルで検索しただけでは私の質問に対する答えが見つからないところまで来ました。

私のプログラムでは、関数によって返される文字列に基づいて、他のクラス内からクラスを呼び出す必要があります。getattr()私は2つの解決策を見つけましglobals()locals()

2番目の解決策に行くことに決め、それを機能させましたが、それがどのように機能しているのか本当にわかりません.

コード例があります:

class Test(object):
    def __init__(self):
        print "WORKS!"

room = globals()['Test'] 
room()

type(room())与えます:

<class '__main__.Test'>

type(room)与えます:

<type 'type'> # What????

クラスオブジェクトのように見えますが、代わりにroom()すべきではありませんか?roomroom()

自分でわからないコードを書くとちょっとばかげているので、助けてください。

4

3 に答える 3

5

ここで何が起こるかは次のとおりです。

class Test(object):
    def __init__(self):
        print "WORKS!"

room = globals()['Test']

ここであなたはあなたが望むTestようroomになりました。これを確認してください:

room is Test

与える必要がありますTrue

type(room())与える:

<class '__main__.Test'>

1つのステップを実行して、逆方向に移動しroom()ます。同じTest()クラスのインスタンスを返します。type()このステップまたはステップを「元に戻す」。オブジェクトのタイプを取得します-これはもちろんですTest

type(room)与える:

<type 'type'> # What????

もちろん、これは(新しいスタイルの)クラスのタイプです。と同じtype(Test)です。


ただし、

私のプログラムでは、関数によって返された文字列に基づいて、他のクラス内からクラスを呼び出す必要があります。私は2つの解決策を見つけました。1つは/を使用する方法で、もう1つは/getattr()を使用する方法です。globals()locals()

明示的に別個のdictを作成する方がよい場合があります。ここでは、そのコンテキストで許可されるオブジェクト/クラス/...と許可されないオブジェクトを完全に制御できます。

于 2012-10-05T12:05:14.373 に答える
1

Python では、クラスもオブジェクトです。これはすべて次のことを行います。

class Test(object):
    def __init__(self):
        print "WORKS!"

クラス オブジェクトを作成し、それを name にバインドしますTest。これと同じくらい:

x = []

リスト オブジェクトを作成し、それを name にバインドしますx

Test()インスタンスを作成するための魔法の構文ではありません。はTest完全に通常の変数検索であり、()完全に通常の「空の引数での呼び出し」です。クラスを呼び出すと、そのクラスのインスタンスが作成されることがあります。

その場合、クラスの名前を文字列として持つことに基づいて選択されたクラスをインスタンス化するという問題は、変数に格納されているオブジェクトを見つけるというより単純な問題に帰着します。xこれは、 string を指定して name にバインドされたリストを取得するのとまったく同じ問題"x"です。古い変数でクラスへの参照を取得したら、それを呼び出してインスタンスを作成するだけです。

globals()グローバルの名前をその値にマッピングする辞書を返します。したがって、リストを取得するのと同じくらい簡単にglobals()['Test']クラスを取得できます。ただし、通常、このように使用するのは優れたスタイルとは見なされません。あなたのモジュールには、関数がそれらの名前を返すように作成できる場合、誤って呼び出されたくない多数の呼び出し可能オブジェクト (他のモジュールからインポートされた束を含む) が含まれている可能性があります。クラスは普通のオブジェクトに過ぎないので、自分で作成した辞書に入れることができます:Testglobals()['x']globals()

classes = {
    'Test': Test,
    'SomethingElse': Something,
    ...
}

これにはもう少し入力が必要ですが、意図した使用法が何であるかを確認するのも簡単です。また、この辞書を他のモジュールに簡単に渡してインスタンス化を別の場所で行うこともできるため、柔軟性が少し高くなります (それはglobals()、しかし、あなたは非常に奇妙になっています)。

さて、存在のためtype(room)type。繰り返しますが、これはクラス自体もオブジェクトであるという事実の単なる結果です。クラスがオブジェクトである場合、クラスのインスタンスでもある必要があります。それは何のクラスですか?type、「タイプのタイプ」。クラスがすべてのインスタンスの共通の動作を定義するのと同じように、クラスはtypeすべてのクラスの共通の動作を定義します。

そして、あなたの頭を悩ませるのtypeは、それ自体のインスタンスです (typeもクラスでありtype、クラスのクラスであるため)。そして、それは (すべてのインスタンスはインスタンスですが、すべてのインスタンスがインスタンスであるとは限らないため)のサブクラスであり、object(すべてがインスタンスであるルート クラスであるため) のインスタンスでもあります。typeobjectobjecttypeobjectobject

typeただし、通常は高度なトピックとして無視できます。:)

于 2012-10-05T14:31:38.813 に答える
1

まず第一に、私はgetattr代わりに行きます。

あなたの例では、room等しいTestとクラスです。そのタイプはtypeです。

を呼び出すとroom()、 がインスタンス化されるTestためroom()、 は のインスタンスとして評価されTest、その型はTestです。

于 2012-10-05T12:01:07.710 に答える