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

PPT*_*Tim 24 python string variables dictionary

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

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

它创建了我可以用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.这是不错的编程实践.

提前致谢!

jcd*_*yer 35

用于创建变量序列的pythonic方法

如果需要一系列变量,请创建一个序列.而不是尝试创建自己的变量,如:

variable0
variable1
variable2
variable3
Run Code Online (Sandbox Code Playgroud)

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

sequence = []
for _ in xrange(10):
    sequence.append(function_that_returns_data())
Run Code Online (Sandbox Code Playgroud)

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

然后您的数据将显示为:

sequence[0]
sequence[1]
sequence[2]
sequence[3]
[...]
sequence[9]
Run Code Online (Sandbox Code Playgroud)

作为额外的奖励,您可以:

for datum in sequence:
    process_data(datum)
Run Code Online (Sandbox Code Playgroud)

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

vars()和locals()

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

locals()['x'] = 4
x = 4
Run Code Online (Sandbox Code Playgroud)

范围与范围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'
Run Code Online (Sandbox Code Playgroud)

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

  • 我认为`vars()['x'] = 4`和`x = 4`实际上只相当于一些时间.如果你在一个函数中执行此操作,并且不在其他地方设置`x`,并且该函数由编译器优化,那么函数后面的`x`的正常查找(即,`y = x + 2`)赢了不行.我认为编译器会缓存它可以看到的变量(可能在编译时定义),并没有考虑到这种类型的shenanigan.如果向函数添加exec语句,则编译器不会尝试优化函数. (2认同)

S.L*_*ott 9

这样做.它更简单.

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

这就是你需要做的一切.

结果将myDict['variable1']通过myDict['variable9']

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


Jus*_*eel 6

从vars的帮助,

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

Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.
Run Code Online (Sandbox Code Playgroud)

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

locals(...)locals() - >字典

Update and return a dictionary containing the current scope's local
Run Code Online (Sandbox Code Playgroud)

变量.

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

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


Vin*_*ars 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")
Run Code Online (Sandbox Code Playgroud)

结果如下:

{'self': Bull(), 'z': 5}
{'y': 'this', 'x': 1}
{'self': Bull()}
{'y': 1, 'self': Bull()}
this
Run Code Online (Sandbox Code Playgroud)