蟒蛇:由groupdict返回改变字典()

问题描述:

它是安全的修改由一个标准库对象的方法返回一个可变对象?蟒蛇:由groupdict返回改变字典()

这里有一个具体的例子;但如果可能的话,我正在寻找一个普遍的答案。

#m is a MatchObject 
#I know there's only one named group in the regex 
#I want to retrieve the name and the value 
g, v = m.groupdict().popitem() 
#do something else with m 

此代码是否安全?我担心通过改变groupdict()我正在破坏对象m(我仍然需要)。

我测试了这一点,并m.groupdict的后续调用()仍然返回原来的字典;但我知道这可能取决于实现。

+0

所以我正确理解答案是: 不,不安全。 Python标准库没有承诺修改m.groupdict()不会破坏MatchObject。 – max 2010-08-23 22:40:43

通常只有保证是安全的,如果文档说明如此。 (在这种情况下,看起来不太可能另一个实现的行为会有所不同)

+0

是的。其他实现*通常*遵循CPython和CPython *通常*保留与其自己以前版本的兼容性。 – Constantin 2010-08-23 11:53:27

groupdict返回一个新的字典,每次:

In [20]: id(m.groupdict()) 
Out[20]: 3075475492L 

In [21]: id(m.groupdict()) 
Out[21]: 3075473588L 

我不能谈论整个标准库,虽然。您应该检查自己,方法是否返回对象内部某个内部存储结构的引用,或者每次调用时都会创建一个新的结构。 groupdict每次创建一个新的。这就是为什么修改结果字典应该是安全的。

+0

谢谢,这有助于。 但是,我不知道我将如何检查该方法返回,除了通过阅读实现代码。当然,我不想依赖任何具体的实现来决定我的代码是否安全。 – max 2010-08-23 07:57:05

在这种情况下,您应该安全,因为MatchObject.groupdict()返回代表匹配组的字典,但每次都是新副本。

dict.popitem()确实改变你正在调用它的字典。

删除并返回字典中的任意(键值为 值)对。

popitem()破坏性 迭代一个字典有用,因为常常在 组算法中使用。如果 字典是空的,调用 popitem()提出了一个KeyError

+0

我怎样才能确定它是一个新的副本?我期望它在Python文档中有说明,但其中 – max 2010-08-23 08:06:43

+0

@max据我所知[[MatchObject]](http://docs.python.org/library/re.html#match-objects)的所有方法和属性仅返回值,因此您不能更改基础对象。我不认为这*具有记录,因为没有任何意义可以改变对象。 – quantumSoup 2010-08-23 13:28:45

+0

@quantumSoup如果我错了,纠正我,但我认为在Python中,你只能返回一个引用 - 而引用可以是内部对象或新创建的对象。 – max 2010-08-23 22:39:25

这里有两个不同的操作在m上执行。第一个,groupdict,创建一个从m字典。第二个,popitem返回字典中的项目,并修改字典(但不包含潜在项目)

所以随后致电m.groupdict()仍然创建字典从相同的m

但是你为什么要用popitem呢?为什么不只是items()

+0

但是我怎么知道groupdict()每次打电话时都会创建一个全新的字典?我担心在某些实现中它可能会提供对内部字典对象的引用。这是否在文档中的任何地方进行了澄清? 关于你的最后一点,当然我可以很容易地切换到非破坏性的.items()[0];我只想举一个简单的例子。 – max 2010-08-23 08:04:41