在Python脚本中从外部数据创建变量

0 投票
3 回答
1797 浏览
提问于 2025-04-16 15:03

我想读取一个外部数据源(比如Excel),然后创建一些变量来存放这些数据。假设数据是按列排列的,每一列都有一个标题,标题就是变量的名字。

我最初的想法是写一个函数,这样我可以方便地重复使用它。而且,我还可以添加一些额外的参数,让这个函数更灵活。

我现在遇到的问题是,我想在Python中通过变量名来引用这些数据(交互式地)。但我不知道怎么做(用函数来实现)。我唯一想到的解决办法是从我的函数中返回变量名和数据(比如以列表的形式),然后像这样处理:

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

names, values = get_data(my_excel)

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

我能不能直接得到相同的结果呢?谢谢,Roel

3 个回答

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 *')"。你可能并不想执行这个命令。

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)
1

如果你只是想为每个名字设置本地变量,可以使用:

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

如果你想要一个更整洁的方式来访问数据,可以使用字典(dict),并从你的函数返回这个字典。

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

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

最后,如果你想把数据当作对象的属性来访问,可以更新一个对象的 __dict__(如果你的列名和某些 特殊的Python方法相同,可能会出现意想不到的行为)。

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

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

撰写回答