如何提取并引用Python模块中定义的变量?
我正在为我公司的测试环境编写一个简单的环境检查脚本。我的目标是能够对每个在特定测试环境实例中定义的主机进行ping测试。这些主机在一个文件中定义,格式如下:
#!/usr/bin/env python
host_ip = '192.168.100.10'
router_ip = '192.168.100.254'
fs_ip = '192.168.200.10'
我该如何以可迭代的方式获取这些值(也就是说,我需要循环遍历并对每个IP地址进行ping测试)?
我查看了local()和vars(),但尝试做这样的事情:
for key, value in vars():
print key, value
却产生了这个错误:
ValueError: too many values to unpack
我已经能够通过检查dir(local_variables)
来提取所有变量的名称,找出那些不包含'__'字符串的值,但这样我得到的是一个字符串列表,我不知道如何从字符串获取同名变量的值。
5 个回答
你需要使用 vars().iteritems()(或者 .items())。
如果你只是遍历像 vars() 这样的字典,实际上只会提取出字典里的键。
举个例子。
>>> for key in vars(): print key
...
__builtins__
__name__
__doc__
key
__package__
>>> for key, value in vars().items(): print key, value
...
__builtins__ <module '__builtin__' (built-in)>
value None
__package__ None
key __doc__
__name__ __main__
__doc__ None
首先,我强烈建议不要那样做。相反,你应该这样:
hosts = {
"host_ip": '192.168.100.10',
"router_ip": '192.168.100.254',
"fs_ip": '192.168.200.10',
}
这样你就可以简单地导入这个模块,并正常引用它——这是一种普通且标准的方式,可以从任何Python代码中访问这些数据:
import config
for host, ip in config.hosts.iteritems():
...
如果你直接访问变量,你会得到很多你不想要的东西,比如一些内置的内容(__builtins__
、__package__
等);还有在设置其他变量时导入的任何东西等等。
你还需要确保你运行的环境和你正在遍历的变量的环境不同,否则在遍历时你会在locals()(或者vars(),或者globals())中创建新的变量,这样就会出现"RuntimeError: dictionary changed size during iteration"
的错误。
这里有一个我常用的小技巧。你在返回字符串名称的列表时已经很接近了,但你需要用到eval()这个函数,才能返回实际对应字符串名称的对象:
hosts = [eval('modulename.' + x) for x in dir(local_variables) if '_ip' in x]
如果我没记错的话,这个方法也没有Glen Maynard提到的locals()和vars()的那些缺点。