2017-08-14 4 views
4

グローバルスコープでのオブジェクトのすべての変数名を取得します。Pythonは - 私は例を挙げて説明します

list_1 = [1, 2, 3] 
list_2 = list_3 = list_1 # reference copy 

print(magic_method(list_1)) 
# Should print ['list_1', 'list_2', 'list_3'] 

set_1 = {'a', 'b'} 
print(magic_method(set_1)) 
# Should print ['set_1'] 

要件:同じ参照を指しているすべての変数の名前を返します。これはPythonでも可能ですか?

私は、globals()locals()を繰り返して、idに等しいと思っています。もっと良いものはありますか?

+0

はクロージャです興味のあるものは? – donkopotamus

+0

@donkopotamus私はそれが複雑である必要はないと思う。私は現在、グローバルな範囲を検討しています。 –

+0

グローバルスコープの 'globals()'は問題ありません。複雑にする必要はありません。私たちが 'is 'を持っているときには、IDを比較する必要はありません。 –

答えて

2

def magic_method(obj): 
    import inspect 
    frame = inspect.currentframe() 
    try: 
     names = [name for name, val in frame.f_back.f_locals.items() if val is obj] 
     names += [name for name, val in frame.f_back.f_globals.items() 
        if val is obj and name not in names] 
     return names 
    finally: 
     del frame 

そして:

def magic_method(obj): 
    return [name for name, val in globals().items() if val is obj] 

あなたも地元の名を欲しい場合、あなたはinspectモジュールを使用することができますが

list_1 = [1, 2, 3] 
list_2 = list_1 

def my_fun(): 
    list_3 = list_1 
    list_2 = list_1 
    print(magic_method(list_1)) 

my_fun() 
>>> ['list_3', 'list_1', 'list_2'] 
+0

@cᴏʟᴅslocalローカル変数も含めるように答えを更新しました。 – jdehesa

+1

これは、 'magic_method'を呼び出す関数のローカル変数でのみ機能することに注意してください。呼び出しスタック上に関数があれば無視されます。'frame.f_back'が' None'を返すまで、コールスタックをループすることができます。 –

+0

@Rawingはい、そうです、私は直属の発信者からの地元の人しか興味がないと思っていましたが、そのようなスタック全体を調べることもできます。 – jdehesa

-2

これは動作します:

def magic_method(var): 
    names = filter(lambda x: globals()[x] is var, globals().keys()) 
    return names 

isは、参照比較を行います。 Python3を使用している場合は、結果の式にlist(...)を追加してください。あなたが行うことができますグローバル変数の場合

+0

'is not' == 'を使用してください。 –

+0

OK、同じ参照ではなく同じ値を参照するには' is'を '=='に変更してください –

+1

質問は*同じオブジェクト*に関するものでした。 2つの別個の100ドル紙幣は同じ紙幣ではありません。 –

関連する問題