2010-08-23 6 views
5

Ist es sicher, ein veränderbares Objekt zu modifizieren, das von einer Methode eines Standardbibliotheksobjekts zurückgegeben wird?python: Wörterbuch ändern von groupdict() zurückgegeben

Hier ist ein spezifisches Beispiel; aber ich suche nach einer allgemeinen Antwort wenn möglich.

#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 

Ist dieser Code sicher? Ich bin besorgt, dass ich mit groupdict() das Objekt m korrumpiere (was ich noch für später brauche).

Ich testete dies aus, und ein nachfolgender Aufruf von m.grouddict() gab immer noch das ursprüngliche Wörterbuch zurück; Aber ich weiß, dass dies von der Implementierung abhängig sein kann.

+0

So verstehe ich richtig, dass die Antwort lautet: Nein, es ist kein Safe. Es gibt in der Python-Standardbibliothek kein Versprechen, dass das Ändern von m.groupdict() das MatchObject nicht beschädigt. – max

Antwort

1

Im Allgemeinen ist es nur garantiert, um sicher zu sein, wenn die Dokumentation so sagt. (In diesem speziellen Fall scheint es sehr unwahrscheinlich, dass sich eine andere Implementierung anders verhält.)

+0

Wahr. Andere Implementierungen * folgen normalerweise * dem, was CPython tut, und CPython * behält normalerweise die Kompatibilität mit seinen eigenen früheren Versionen bei. – Constantin

0

groupdict gibt ein neues Wörterbuch jedes Mal: ​​

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

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

Ich kann allerdings nicht über ganze Standardbibliothek sprechen. Sie sollten selbst überprüfen, ob eine Methode einen Verweis auf eine intern gespeicherte Struktur im Objekt zurückgibt oder bei jedem Aufruf eine neue erstellt. groupdict erstellt jedes Mal ein neues. Aus diesem Grund sollte es sicher sein, das Ergebniswörterbuch zu ändern.

+0

Danke, das hilft. Allerdings bin ich nicht sicher, wie ich überprüfen würde, was die Methode zurückgibt, außer durch das Lesen des Implementierungscodes. Natürlich möchte ich mich bei der Entscheidung, ob mein Code sicher ist, nicht auf eine bestimmte Implementierung verlassen. – max

0

Sie sollten in diesem speziellen Fall sicher sein, da MatchObject.groupdict() ein Wörterbuch zurückgibt, das die übereinstimmenden Gruppen darstellt, aber es ist jedes Mal eine neue Kopie.

dict.popitem()does ändern Sie das Wörterbuch, das Sie aufrufen, obwohl.

Entfernen Sie ein beliebiges (Schlüssel, Wert) Paar aus dem Wörterbuch und geben Sie es zurück.

popitem() ist nützlich, um destruktiv Iterierte über einem Wörterbuch, wie oft in Satz Algorithmen verwendet. Wenn das Wörterbuch leer ist, wird durch Aufrufen von popitem() ein KeyError ausgelöst.

+0

Wie kann ich sicher sein, dass es sich um eine neue Kopie handelt? Ich erwarte, dass es irgendwo in der Python-Dokumentation steht, aber wo – max

+0

@max Soweit ich kenne alle Methoden von 'MatchObject' (http://docs.python.org/library/re.html#match-objects) und Eigenschaften geben nur Werte zurück und daher können Sie das zugrunde liegende Objekt nicht ändern. Ich glaube nicht, dass das * dokumentiert * sein muss, da es keinen Sinn ergeben würde, das Objekt zu verändern. – quantumSoup

+0

@quantumSoup Korrigieren Sie mich, wenn ich falsch liege, aber ich dachte in Python können Sie nur eine Referenz zurückgeben - und eine Referenz kann zu einem internen Objekt oder zu einem neu erstellten Objekt sein. – max

0

Hier werden zwei verschiedene Operationen unter m ausgeführt. Die erste, groupdict, erstellt ein Wörterbuch von m. Die zweite, popitem, gibt ein Element aus dem Wörterbuch zurück und ändert das Wörterbuch (aber nicht das zugrunde liegende Element).

So nachfolgende Aufrufe an m.groupdict() noch erstellen das Wörterbuch aus der gleichen m.

Aber warum verwenden Sie überhaupt popitem? Warum nicht einfach items()?

+0

Aber woher weiß ich, dass groupdict() jedes Mal ein neues Wörterbuch erstellt, wenn ich es anrufe? Ich fürchte, in einigen Implementierungen könnte es einen Verweis auf ein internes Dictionary-Objekt geben. Ist dies irgendwo in der Dokumentation geklärt? In Bezug auf Ihren letzten Punkt könnte ich natürlich leicht auf die zerstörungsfreie .items() [0]; Ich wollte nur ein einfaches Beispiel geben. – max