2017-08-14 67 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): 
    return [name for name, val in globals().items() if val is obj] 

如果你想本地的名字也一樣,你可以使用inspect模塊:

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 

然後:

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ᴏʟᴅsᴘᴇᴇᴅ我已經更新了包含局部變量的答案。 – jdehesa

+1

請注意,這隻適用於調用'magic_method'的函數的局部變量。如果在callstack上還有更多的功能,他們會被忽略。你可以循環調用堆棧直到'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

應該使用不是'==' –

+0

好吧,它不是相同的引用,但相同的值,更改'=='爲'is'來獲取引用 –

+1

問題是關於*相同的對象*。兩張不同的賬單不是同一張紙幣。 –