有没有一种方法可以将Python中的字典提取到本地命名空间中?

6

PHP有一个名为extract()的函数,它以关联数组作为参数,并将键的值分配给键的变量。在Python中是否有类似的功能呢?快速的谷歌搜索并没有立即向我展示如何实现这一点。我怀疑可以使用exec()函数来实现,但如果有一些函数可以帮助我做到这一点就太好了。


1
选择特定功能的一个很少有好理由是“其他语言也可以实现”。 - Ignacio Vazquez-Abrams
这对我来说不是“必须拥有”的功能,我只是认为它对于使用 **kwargs 的函数来说很不错。 - Kevin
2
如果您在函数体中静态地知道使用kwargs接收的名称,并且可以键入它们,则不需要使用**kwargs - Mike Graham
3个回答

5

由于修改locals()返回的字典不安全,因此需要注意。

>>> d={'a':6, 'b':"hello", 'c':set()}
>>> exec '\n'.join("%s=%r"%i for i in d.items())
>>> a
6
>>> b
'hello'
>>> c
set([])

但是像这样使用exec是很丑陋的。你应该重新设计,这样就不需要动态地添加到你的本地命名空间中。
编辑:请参见Mike在评论中对使用repr的保留意见。
>>> d={'a':6, 'b':"hello", 'c':set()}
>>> exec '\n'.join("%s=d['%s']"%(k,k) for k in d)
>>> id(d['c'])
3079176684L
>>> id(c)
3079176684L

谢谢,我会使用这个。我之前提到过我不需要这个功能,只是觉得拥有它很酷。 - Kevin
1
虽然我不认为任何人真正需要这个功能,但重新设计代码的一种方法是将字典传递到一个带有**kwargs的函数中,其中字典将被清晰地解包到本地命名空间中。 - Will Hardy
这段代码有问题。如果你这样做,你会引用字典本身,而不是提取对象的reprs,这在一般情况下是行不通的。例如,你创建了一个新的集合,而不是使用传递的集合,如果我传递给你一个不同类型的集合,比如一个没有有用的“repr”的集合,那么你就会陷入困境。 - Mike Graham
@Mike,感谢您指出这一点——可以直接从字典中使用引用。 - John La Rooy

4

尝试:

    locals().update(my_dict)

编辑:

gnibbler 提出了一个非常有价值的观点,即不应修改本地变量(参见:http://docs.python.org/library/functions.html#locals)。但是,Python文档并没有说这样做是不安全的,它只是说对本地变量的更改可能不会影响变量的值。在回答问题之前,我尝试了一下我的Python 2.6 IDLE,发现更新本地变量确实可以工作,在全局范围和函数内部都可以。这就是为什么我不删除我的答案,而是添加一个警告,即它可能在某些(平台特定?)情况下可以工作,但不能保证。


4
修改locals()并不安全。请参考http://docs.python.org/library/functions.html#locals。 - John La Rooy
我不知道,你有支持这个的链接吗?编辑:我在这里发现locals()是只读的,在IDLE 2.6 shell中并非如此... - Tomasz Zieliński
这不是最明智的选择,但对于非正式使用来说足够了。 - Bite code
1
链接被从我的上面的评论中删除了,它是示例8.12,网址为:http://diveintopython.org/html_processing/locals_and_globals.html - Tomasz Zieliński

-1

修改locals()字典可能是一种解决方案,但文档说,http://docs.python.org/library/functions.html#

注意:不应修改此字典的内容;更改可能不会影响解释器使用的局部和自由变量的值。

所以问题是为什么你需要它?可能有更好的方法来实现你想要实现的目标。

另外,为什么不能直接访问字典或将它们分配给变量?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接