2010-08-23 13 views
5

È sicuro modificare un oggetto mutabile restituito da un metodo di un oggetto libreria standard?python: modifica dizionario restituito da groupdict()

Ecco un esempio specifico; ma sto cercando una risposta generale se possibile.

#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 

Questo codice è sicuro? Sono preoccupato che cambiando groupdict() sto corrompendo l'oggetto m (di cui ho ancora bisogno per dopo).

Ho provato questo, e una successiva chiamata a m.groupdict() ancora restituito il dizionario originale; ma per quanto ne so, questo potrebbe dipendere dall'implementazione.

+0

Quindi ho capito correttamente che la risposta è: No, non è sicuro. Non c'è alcuna promessa dalla libreria standard Python che la modifica di m.groupdict() non danneggi il MatchObject. – max

risposta

1

Generalmente è solo garantito per essere sicuro se la documentazione lo dice. (In questo caso particolare sembra molto improbabile che un'altra implementazione si comporti diversamente.)

+0

Vero. Altre implementazioni * di solito * seguono ciò che fa CPython e CPython * di solito * preserva la compatibilità con le sue versioni precedenti. – Constantin

0

groupdict restituisce un nuovo dizionario ogni volta:

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

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

Non posso parlare di tutta la libreria standard però. È necessario verificare se un metodo restituisce un riferimento ad alcune strutture memorizzate internamente all'interno dell'oggetto o ne crea uno nuovo ogni volta che viene chiamato. groupdict crea uno nuovo ogni volta. Questo è il motivo per cui dovrebbe essere sicuro modificare il dizionario dei risultati.

+0

Grazie, questo aiuta. Tuttavia, non sono sicuro di come controllare il metodo restituito, oltre a leggere il codice di implementazione. Naturalmente, non voglio fare affidamento su alcuna implementazione specifica per decidere se il mio codice è sicuro. – max

0

Si dovrebbe essere sicuri in questo caso particolare, perché MatchObject.groupdict() restituisce un dizionario che rappresenta i gruppi corrispondenti, ma è una nuova copia ogni volta.

dict.popitem()fa cambiare il dizionario su cui si sta chiamando.

Rimuovere e restituire una coppia arbitraria (chiave, ) dal dizionario.

popitem() è utile distruttivo iterazioni su una dizionario, come spesso utilizzato negli algoritmi set. Se il dizionario è vuoto, chiamando popitem() alza uno KeyError.

+0

Come posso essere certo che si tratta di una nuova copia? Mi aspetto che sia indicato da qualche parte nella documentazione di Python, ma dove – max

+0

@max Per quanto ne so tutti i metodi di ['MatchObject'] (http://docs.python.org/library/re.html#match-objects) e proprietà restituiscono solo valori e quindi non è possibile modificare l'oggetto sottostante. Non penso che * abbia * da documentare, dal momento che non avrebbe senso cambiare l'oggetto. – quantumSoup

+0

@quantumSoup Correggimi se ho torto, ma ho pensato che in Python puoi solo restituire un riferimento - e un riferimento può essere a un oggetto interno oa un oggetto appena creato. – max

0

Qui ci sono due diverse operazioni eseguite su m. Il primo, groupdict, crea un dizionario da m. Il secondo, popitem, restituisce un elemento dal dizionario e modifica il dizionario (ma non l'elemento sottostante).

Quindi le chiamate successive a m.groupdict() rappresentano ancora creare il dizionario dallo stesso m.

Ma perché stai usando popitem? Perché non solo items()?

+0

Ma come faccio a sapere che groupdict() crea effettivamente un dizionario nuovo ogni volta che lo chiamo? Ho paura che in alcune implementazioni possa fornire un riferimento a un oggetto dizionario interno. Questo è chiarito ovunque nella documentazione? Per quanto riguarda il tuo ultimo punto, ovviamente potrei facilmente passare al non distruttivo .items() [0]; Volevo solo dare un semplice esempio. – max