2016-02-19 78 views
0

我已經創建了這樣的namedtuple。從字符串中檢索namedvalue值

Named_Tuple_1 = namedtuple("Coordinates", ["x", "y", "z"], verbose=False, rename=False) 

Point_1 = Named_Tuple_1(x=1, y=1, z=1) 
Point_2 = Named_Tuple_1(x=2, y=2, z=2) 
Point_3 = Named_Tuple_1(x=3, y=3, z=3) 

我可以像這樣輕鬆地訪問值。

Point_2.x 

但是,當我嘗試從輸入框中獲取Point_2時,出現此錯誤。

AttributeError: 'str' object has no attribute 'x' 

因此,我得知輸入框返回字符串值。

如何從字符串中獲取namedtuple值?

String_1 = "Point_2" 
String_1 ??? 

謝謝。

對不起,我感到困惑。希望這更清楚。

所以,我決定在Point_2.x中添加Point_1.x並將總數添加到我的對話框中作爲標籤。

Named_Tuple_1 = namedtuple("Coordinates", ["x", "y", "z"], verbose=False, rename=False) 
Point_1 = Named_Tuple_1(x=1, y=2, z=3) 
Point_2 = Named_Tuple_1(x=4, y=5, z=6) 
Point_3 = Named_Tuple_1(x=7, y=8, z=9) 

def ADD_x_1(): 
    Sum_of_x = Point_1.x + Point_2.x 
    My_Label_1 = Label(Dialog, text=Sum_of_x) 
    My_Label_1.pack() 

Dialog = Tk() 
My_Button_1 = Button(Dialog, text="Add x Value", command=ADD_x_1) 
My_Button_1.pack() 
Dialog.mainloop() 

現在我想做同樣的事情,但有一個用戶決定添加哪個點。

def ADD_x_2(): 
    First_Point_x = My_Entry_1.get().x 
    Second_Point_x = My_Entry_2.get().x 
    Sum_of_x = First_Point_x + Second_Point_x 
    My_Label_3 = Label(Dialog, text=Sum_of_x) 
    My_Label_3.pack() 

Dialog = Tk() 
My_Label_1 = Label(Dialog, text="Select first point") 
My_Label_1.pack() 
My_Entry_1 = Entry(Dialog, bd=2, width=10) 
My_Entry_1.pack() 
My_Label_2 = Label(Dialog, text="Select second point") 
My_Label_2.pack() 
My_Entry_2 = Entry(Dialog, bd=2, width=10) 
My_Entry_2.pack() 
My_Button_2 = Button(Dialog, text="Add x Value", command=ADD_x_2) 
My_Button_2.pack() 
Dialog.mainloop() 

我的問題是My_Entry_1.get()和My_Entry_2.get()是字符串。我得到了錯誤AttributeError:'str'對象沒有屬性'x'。

所以我的問題是如何從My_Entry_1和My_Entry_2中獲取字符串來訪問x值?

對不起,再次混淆。

謝謝。

回答

2

我不確定在這種情況下什麼輸入框,但我認爲你有幾個選擇在這裏。

1)將這些點輸入到字典中,並通過從輸入框中返回的字符串對其進行索引。

point_dict = {'Point_1': Point_1, 'Point_2': Point_2, 'Point_3': Point_3} 
entry_point = {{however you got the string from the entrypoint}} 
point = point_dict[entry_point] 
point.x 

2)如果這些位於模塊級別,則可以嘗試從模塊上下文中獲取變量。 )https://docs.python.org/3/library/functions.html#eval ,或者甚至更好當地人(:

import sys 
modname = globals()['__name__'] 
modobj = sys.modules[modname] 
point = getattr(modobj, 'Point_1') 

3)如果你想在一個函數中引用它,你可以嘗試的eval https://docs.python.org/2/library/functions.html#locals

##Point_1 = eval('Point_1') risk due to executing arbitrary code 
Point_1 = locals()['Point_1'] # Use this instead 
+0

因爲你有一個確切的名字,所以我會切換#3來使用'locals()''dict'在'eval'上。避免'eval'的安全風險。另外,在#2中不需要'globals',你只需直接使用'sys.modules [__ name __]','__name__'周圍不需要引號,因爲'__name__'總是存在於模塊中(除非你已經對它進行了映射本地爲上帝知道什麼原因)。 – ShadowRanger

+0

對不起。這就是我的意思。 My_Entry = Entry(對話框,寬度= 10).pack() – GrandJoss

+1

@GrandJoss:像#1這樣的東西幾乎肯定是你想要做的。 – Gerrat

0

你一般不會這麼做(這是unsafe任意輸入),但你可以使用eval

String_1 = eval('Point_2") 

現在它指向已經存在的變量Point_2

+0

這工作得很好。我可以使用String_1.x來獲取來自輸入框的Point_2的x值。但你用這種方法不安全讓我害怕。我是編碼的新手,我不想搞亂我的代碼。如果我的namedtuple是固定的,並且永遠不會改變,我很樂意使用這種方法嗎? – GrandJoss

+0

@GrandJoss:'eval'可以執行任意的Python代碼,而不僅僅是查找變量,這就是爲什麼它皺起了眉頭。使用'globals()','locals()'或'vars()'(取決於名稱存在的位置)返回的'dict'意味着他們可以做的最糟糕的事情是讓您讀取一個已存在的變量或者引發'KeyError ''),其中'eval'讓他們通過輸入'[__import __('os')來刪除工作目錄中的所有文件。 ]'而不是'Point_2'。 – ShadowRanger

+0

@GrandJoss:正如@ ShadowRanger所提到的,如果你真的不知道自己在做什麼,這可能不是你想要的。 'locals()'好一點,但我想你可能想重新考慮你的設計。我懷疑你需要做任何你想做的事情。也許詳細說明你的問題,讓我們知道你爲什麼要這樣做。 – Gerrat