【问题标题】:Python creating dynamic global variable from listPython从列表中创建动态全局变量
【发布时间】:2013-04-11 23:53:24
【问题描述】:

我正在尝试制作通用配置,从而配置解析器。有两个配置文件说 A 和 B。我想解析部分并根据硬编码列表从它们中生成全局值。

这是一个例子:

在配置文件中:

[section]
var1 = value1
var2 = value2

在全球范围内:

some_global_list = [ ["var1","var2"], ["var3","var4"] ] 

通过 ConfigParser 在函数中解压这些值:

configparser = ConfigParser.RawConfigParser()
configparser.read(some_config_filename)

for variables in some_global_list:
    globals()[section]=dict()
    for element in configparser.items(section):
        globals()[section].update({element[0]:element[1]})

这很好用......但是。 globals() 的范围似乎仅限于功能,这显然不是我想要的。我只能在该函数中访问变量。

有人可以分享更好但更简单的想法吗? 我知道我可能会将代码移至 main 而不必担心,但我认为这不是一个好主意。 我还考虑过制作一些生成器(抱歉这里有伪代码):

在全球范围内:

for x in some_global_list:
    globals()[x] = x

还尝试将其添加到函数中:

for x in some_global_list[0]:
    global x

但一无所获。

编辑:

经过下面的讨论,这里是:

问题解决如下:

  1. 将整个配置从主脚本移至模块
  2. 从模块导入(从模块导入某些功能)配置
  3. 删除了 globals() 实际上不需要它们,因为函数被改变了一点:

在功能中:

def somefunction:
#(...)

configparser = ConfigParser.RawConfigParser()
configparser.read(some_config_filename)

temp_list=[]
for variables in some_global_list:
    tmp=dict()
    for element in configparser.items(section):
    tmp.update({element[0]:element[1]})
temp_list.append (tmp)
return temp_list #this is pack for one file.   

现在在主脚本中

tmp=[]
for i,conf_file in enumerate([args.conf1,args.conf2,args.conf3]):
    if conf_file:
        try:
            tmp.append([function(params...)])
        except:
            #handling here
        #but since i needed those config names as global variables 
    for j,variable_set in enumerate(known_variable_names[i]):
        globals()[variable_set] = tmp[i][j]

如此不幸的黑客攻击存在。但似乎有效。谢谢你们的帮助。

我接受(如果可能的话)下面的答案,因为它给了我一个好主意:)

【问题讨论】:

  • 停止使用全局变量并使用dict() 来代替您的部分?很少需要戳globals()
  • 是的,我明白你想做什么,我是说你不应该那样做,期间。如果您的用户在配置文件中添加了一个名为 configparser 的部分怎么办?您现在让用户控制的配置文件破坏您的代码。
  • 不,你不应该从配置文件中设置全局变量,这就是我的意思。你可以从一个函数中设置全局变量,我是说你不应该那样做
  • @brainovergrow:然后为您的配置信息 config = {} 设置 one 全局并在您的函数中添加到该映射。 config[section] = dict()
  • @brainovergrow:然后为它们创建单独的配置全局变量。或者将它们嵌套更深一层。我想说的是,您应该使用您的globals() 作为您的配置的全局字典。您需要做的就是添加您使用的 一个 命名字典全局。

标签: python dynamic global-variables


【解决方案1】:

解决此问题的一种简单方法是在您的应用程序包中的__init__.py 中执行类似以下操作:

app_config = read_config()

def read_config():
    configparser = ConfigParser.RawConfigParser()
    configparser.read(some_config_filename)
    return configparser.as_dict() #An imaginery method which returns the vals as dict.

“app_config”变量可以导入应用程序中的任何其他模块。

【讨论】:

  • 我会检查的。虽然 - 不确定我是否可以从 argparse 传递 some_config_filename,并避免将所有配置步骤移至 init ;)
  • @brainovergrow 您应该考虑将您的引导代码集中到实例 bootstrap.py 的单个模块中。
  • 嗯,但是如果我将它模块化,我想我需要两个额外的文件:__init__.py 和 bootstrap.py,对吗?
  • @brainovergrow 如果你有一个 init.py 并且如果应用程序很小,那么可以在其中完成初始化。但似乎您正在编写一个从命令行运行的脚本,并且配置文件路径可能作为 CLI 参数传递。这是正确的吗?
  • 配置路径可以作为选项传递(使用 argparse 默认值)。我将它传递给 configreader 函数,所以这里没问题。我已将 configreader 功能移至模块,并且可以使用方便的“从 somemodule 导入 configreader”。和以前一样,但我想我可以将所需的配置传递回主脚本。
猜你喜欢
  • 2018-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-25
  • 1970-01-01
相关资源
最近更新 更多