Python:使用vars()将字符串赋给变量

时间:2010-02-23 19:09:41

标签: python string dictionary variables

我发现能够在运行时创建新变量并创建结果字典以便稍后处理(即写入文件)非常有用:

myDict = {}
for i in range (1,10):
    temp = "variable"+str(i) 
    vars()[temp] = myFunctionThatReturnsData() # variable1= data1, variable2 = data2,etc.
    myDict[temp] = vars(temp)

创建了我可以用myDict [result1]调用的字典条目[result1:data1]。我一直在使用vars()而没有真正了解我在做什么。我把它vars()返回一个包含局部变量(?)和

的字典
  

vars()[x] = y

创建[x:y]的新词典条目?

我有一个脚本,我在其中传递了使用{input1:data1,input2:data2}编写的字典,我使用此方法迭代所有值,存储所有结果,并将其输出到文件。这段代码在一个类中的函数内部,并且正在工作。

我的困惑之处在于我已经阅读了各种关于如何不与locals()混淆的帖子,以及vars()与locals()或者globals()等效(?)的方式。

所以我的问题(至少)是双重的:

1. vars()究竟是什么,特别是vars()[x] = y,

2.这本词典的范围是什么(在编写更大的程序时我需要记住的是

3.这是否是良好的编程习惯。

提前致谢!

6 个答案:

答案 0 :(得分:35)

创建变量序列的pythonic方法

如果需要一系列变量,请创建一个序列。而不是尝试创建像:

这样的独立变量
variable0
variable1
variable2
variable3

您应该考虑创建list。这类似于S.Lott的建议(S.Lott通常有很好的建议),但更整齐地映射到你的for循环:

sequence = []
for _ in xrange(10):
    sequence.append(function_that_returns_data())

(请注意,我们丢弃了循环变量(_)。我们只是试图获得10次传递。)

然后您的数据将显示为:

sequence[0]
sequence[1]
sequence[2]
sequence[3]
[...]
sequence[9]

作为额外奖励,您可以:

for datum in sequence:
    process_data(datum)

首先,你可能会在你的序列从0开始时抽搐。你可以通过各种扭曲让你的实际数据从1开始,但它比它的价值更痛苦。我建议你习惯于拥有从零开始的列表。一切都围绕在他们周围,他们开始很快就感到自然。

vars()和locals()

现在,回答你问题的另一部分。 vars()(或locals())提供对python创建的变量的低级访问。因此,以下两行是等效的。

locals()['x'] = 4
x = 4

vars()['x']的范围与x的范围完全相同。 locals()(或vars())的一个问题是它会让你把东西放在命名空间中,而这些东西是你无法通过常规手段从命名空间中获取的。所以你可以做这样的事情:locals()[4] = 'An integer',但是如果不再使用locals就无法恢复原状,因为本地命名空间(和所有python命名空间一样)只是为了保存字符串。

>>> x = 5
>>> dir()
['__builtins__', '__doc__', '__name__', 'x']
>>> locals()[4] = 'An integer'
>>> dir()
[4, '__builtins__', '__doc__', '__name__', 'x']
>>> x
5
>>> 4
4
>>> locals()[4]
'An integer'

注意4不会返回与locals()[4]相同的东西。这可能会导致一些意外的,难以调试的问题。这是避免使用locals()的一个原因。另一个原因是,为了做python提供更简单,更不容易出错的方法(比如创建一系列变量),通常会遇到很多复杂问题。

答案 1 :(得分:9)

这样做。它更简单。

myDict = {}
for i in range (1,10):
    temp = "variable"+str(i) 
    myDict[temp] = myFunctionThatReturnsData() # variable1= data1, variable2 = data2,etc.

这就是你需要做的一切。

结果将是myDict['variable1']myDict['variable9']

您很少需要vars()locals()。只是停止使用它们并使用普通变量和普通字典。尽量避免你不理解的事情,并坚持使用简单明了的东西。

答案 2 :(得分:6)

来自vars的帮助,

  

VARS(...)       vars([object]) - >字典

Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.

你正在使用它没有vars,所以让我们看看本地人的帮助()

  

当地人(...)       locals() - >字典

Update and return a dictionary containing the current scope's local
     

变量。

所以这先回答两个问题。 vars()将字典返回给局部变量,该变量由变量名称索引为字符串。范围是本地的。

我不确定第三个问题,但它确实看起来像一个不是一个好兆头的黑客。我想如果你只是在正确的范围内使用它,你就可以使用它。

答案 3 :(得分:5)

jcdyer非常清楚地解释了这些概念,Justin Peel清楚地说明了vars()locals()做了什么。但是一个小例子总能加快理解。

class Bull(object):

    def __init__(self):
        self.x = 1
        self.y = "this"

    def __repr__(self):
        return "Bull()"

    def test1(self):
        z = 5
        return vars()

    def test2(self):
        y = "that"
        return vars(self)

    def test3(self):
        return locals()

    def test4(self):
        y = 1
        return locals()

if __name__ == "__main__":
    b = Bull()
    print b.test1()
    print b.test2()
    print b.test3()
    print b.test4()
    print vars(b).get("y")

结果是:

{'self': Bull(), 'z': 5}
{'y': 'this', 'x': 1}
{'self': Bull()}
{'y': 1, 'self': Bull()}
this

答案 4 :(得分:3)

我可以回答第3点:这不是很好的编程习惯。我并不确切地知道你想要完成什么,但我确信有一种更优雅的方式可以不使用locals()(根据{{1}与vars()相同)在交互式Python shell中。)

答案 5 :(得分:2)

以这种方式使用vars / locals或globals是(a)不良做法和(b)在所有情况下都不起作用。有关详细信息,请参阅Dynamically set local variable。底线:只使用dicts - 这就是他们的用途。