2010-08-23 94 views
5

它是安全的修改由一個標準庫對象的方法返回一個可變對象?蟒蛇:由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

回答

1

通常只有保證是安全的,如果文檔說明如此。 (在這種情況下,看起來不太可能另一個實現的行爲會有所不同)

+0

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

0

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

0

在這種情況下,您應該安全,因爲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

0

這裏有兩個不同的操作在m上執行。第一個,groupdict,創建一個從m字典。第二個,popitem返回字典中的項目,並修改字典(但不包含潛在項目)

所以隨後致電m.groupdict()仍然創建字典從相同的m

但是你爲什麼要用popitem呢?爲什麼不只是items()

+0

但是我怎麼知道groupdict()每次打電話時都會創建一個全新的字典?我擔心在某些實現中它可能會提供對內部字典對象的引用。這是否在文檔中的任何地方進行了澄清? 關於你的最後一點,當然我可以很容易地切換到非破壞性的.items()[0];我只想舉一個簡單的例子。 – max 2010-08-23 08:04:41