2016-02-19 75 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