2011-04-04 32 views
0

我想读取外部数据源(excel)并创建包含数据的变量。假设数据在列中,每列都有一个带有变量名称的头部。从python脚本中的外部数据创建变量

我的第一个想法是编写一个函数,以便我可以轻松地重用它。此外,我可以轻松地提供一些额外的关键字参数,使功能更通用。

我面临的问题是我想通过变量名称来引用python中的数据(交互式地)。我不知道该怎么做(用一个函数)。我看到的唯一的解决办法是从我的函数返回的变量名和数据(例如,作为列表),并且做这样的事情:

def get_data() 
    (...) 
    return names, values 

names, values = get_data(my_excel) 

for n,v in zip(names, values): 
    exec(''.join([n, '= v'])) 

我可以直接得到相同的结果? 谢谢, 罗埃尔

+0

谢谢大家的回答。选择接受的答案是困难的,因为你们都贡献了自己的东西并且学会了我。我最终选择使用@lazyr的“对象”方法,因为它使我能够轻松访问我的数据(此外,Ipython控制台可以自动完成属性,所以非常实用!) – saroele 2011-04-05 08:21:11

回答

1

如果你只是想设置局部变量的名称每个名称,用途:

for n, v in zip(names, values): 
    locals()[n] = v 

如果你宁愿希望有一个单一的对象来访问数据,这是更干净,只需使用字典,并从你的函数返回。

def get_data(): 
    (...) 
    return dict(zip(names, values)) 

要访问名称“a”的值,只需使用get_data()["a"]

最后,如果要访问数据作为对象的属性,可以更新对象的__dict__(如果任何列名称与任何special python methods相同,则可能会发生意外行为)。

class Data(object): 
    def __init__(self, my_excel): 
     (...) 
     self.__dict__.update(zip(names, values)) 

data = Data("test.xls") 
print data.a 
+0

非常感谢您的回答。更新当地人看起来像是一个很好的技巧,可以将数据存储在脚本中,而无需一直键入data.a。 – saroele 2011-04-04 13:55:28

+0

虽然这真的是个问题吗?你只需要输入'数据'。第一次写程序的时候有几次,然后终身完成。作为交换,你*知道* data.foo不会干扰你的“真正的”变量foo。 – 2011-04-04 14:25:09

+0

嗯,这是因为我想制作图表等交互式,就像在matlab命令窗口中做的那样。这需要经常输入变量。但事实上,当我可以使用上面所示的对象方法时,这不是一个真正的问题。它比词典更容易:'data.a'而不是'data ['a']' – saroele 2011-04-04 14:29:10

2

使用字典存储从名称到值的映射,而不是创建局部变量。

def get_data(excel_document): 
    mapping = {} 
    mapping['name1'] = 'value1' 
    # ... 
    return mapping 

mapping = get_data(my_excel) 
for name, value in mapping: 
    # use them 

如果你真的想从映射填充的变量,你可以修改globals()(或locals()),但它通常被认为是不好的做法。

mapping = get_data(my_excel) 
globals().update(mapping) 
+0

感谢您的回答。你说更新globals()被认为是不好的做法。来自@lazyr的答案似乎也是如此,但是与当地人一样,这看起来是一个很好的中间解决方案,或者这也被认为是不好的做法? – saroele 2011-04-04 13:52:56

+0

更改'locals()'也经常被认为是不好的做法,因为你不能轻易推断出什么变量只是通过读取代码来定义的(更新'globals()'时更糟糕))。这违背了最小惊喜的原则,并且会使代码更难理解。如果这只是一个小脚本,那么它可能是好的,但对于较大的应用程序,您应该考虑其他选择。 – 2011-04-04 13:56:25

+0

我想在这种情况下,我可以忍受它:我想以类似matlab的方式使用变量来使try/error方法中的图形。键入plt.plot(Temp1)比plt.plot(d.Temp1)更容易(如果d是字典)。 (顺便说一下,我如何在这个评论部分中对代码进行格式化?) – saroele 2011-04-04 14:08:28

1

传统的方法是将键/值对填入字典中,以便您可以轻松地将整个结构传递给其他函数。如果你真的要存储这些作为替代属性字典键,可以考虑创建一个类来保存它们:

class Values(object): pass 
store = Values() 
for key, value in zip(names, values): 
    setattr(store, key, value) 

这令变量在自己的命名空间,独立于您正在运行的代码。这几乎总是一件好事。如果你得到一个名为“my_excel”头部的电子表格?突然之间,您已经失去了访问您的原始my_excel对象的机会,如果您再次需要它,这会非常不方便。

但是无论如何,除非您确切知道自己在做什么,否则绝对不应该使用exec。即使如此,也不要使用exec。例如,我知道您的代码是如何工作的,并向您发送电子表格"os.system('echo rm -rf *')"。你可能并不是真的想要执行它。

+0

这是一个清楚的例子,为什么使用exec可能确实是危险的。我不知道你的代码是干什么的,但我想我不想尝试:-) – saroele 2011-04-04 13:46:59

+0

嗯,这个/这只是一个无害的小印刷语句,所以如果有人复制,我不会受到指责 - 看看它是否真的有效。 :-) – 2011-04-04 13:53:15