1

これを尋ねる前に、注意してください:デバッグの目的でこれが必要です。これは悪い黒魔術になることはわかっていますが、オブジェクトをより簡単に識別できるように、デバッグ中にのみ使用したいと思います。

こんな感じです。属性としていくつかのインスタンスAを作成するクラスのオブジェクトがあります。B

class A(object):
    def __init__(self)
        self.vanilla_b = B()
        self.chocolate_b = B()

class B(object):
    def __init__(self):
        # ...

私が欲しいのは、で、それが与えられた属性名またはB.__init__それを理解し、それをこの特定の属性として配置することです。"vanilla_b".nameB

次に、デバッグ中にBオブジェクトが浮かんでいるのを見ると、それがどれであるかを知ることができました。

これを行う方法はありますか?

4

4 に答える 4

2

sys._getframeを使用して が呼び出された行番号を取得し、次にinspect.getsourcelinesB()を使用して実際のコード行を取得できます。そこからコード行を解析して、割り当てられているものを取得できます。B()

import sys
import inspect

class A(object):
    def __init__(self):
        self.vanilla_b = B()
        self.chocolate_b = B()

class B(object):
    def __init__(self):
        line_num = sys._getframe().f_back.f_lineno
        lines = inspect.getsourcelines( sys.modules[__name__] )[0]
        line = lines[line_num - 1]
        attr = line.split("=")[0].split(".")[1].strip()
        print "B() is being assigned to", attr

A()

上記のコードを python スクリプトに入れて実行すると、出力されます

B() is being assigned to vanilla_b
B() is being assigned to chocolate_b

ただし、これは__main__組み込みモジュールであるため、Python コマンド プロンプトでは機能しません。そのため、inspect モジュールはそのソース行を取得できません。したがって、コードが組み込みモジュールから呼び出された場合に備えて、これを try/catch ブロックまたは何かでラップすることをお勧めします。

記録としては、これはおそらく悪い考えですが、あなたはそれが良い習慣ではないことを認識しており、デバッグのためにのみ行っていると言っているので、うまくいけば、この種のトリックを賢く使用できるようになります.

于 2010-04-09T15:39:18.640 に答える
0

これはおそらくあなたが探している答えではありませんが、おそらくこれに沿って何かをすることができます:

class A(object):
    def __init__(self):
        attrs = ('vanilla_b', 'chocolate_b')

        for attr in attrs:
            instance = B()
            setattr(self, attr, instance)
            instance.name = attr

その動作をスーパークラスにラップしてみてください。

于 2010-04-09T15:32:45.047 に答える
0

コードを制御できる場合は、単純にそれを実行してから、黒魔術に頼る方がよいでしょう。

class A(object):
    def __init__(self)
        self.vanilla_b = B(name="vanilla_b")
        self.chocolate_b = B(name="chocolate_b")

それ以外の場合は、inspect モジュールを使用して、前のフレームで locals と self を調べ、vodoo を実行できます。

于 2010-04-09T15:35:49.527 に答える
-1

それほど魔法ではありませんが、次のとおりです。

class A(object):
    def __init__(self)
        self.vanilla_b = B(self)
        self.chocolate_b = B(self)

と:

class B(object):
    def __init__(self, a):
        for i in dir(a):
            if getattr(a, i) == self:
                pass # store it somewhere now

編集: 申し訳ありませんが、これは機能しません。B. initは、A の参照が設定される前に実行されます。

于 2010-04-09T15:40:03.820 に答える