2013-01-21 9 views
9

Solo una domanda fondamentale per quanto riguarda pitone e .join() metodo:generatore di Python e .join

file1 = open(f1,"r") 
file2 = open(f2,"r") 
file3 = open("results","w") 

diff = difflib.Differ() 
result = diff.compare(file1.read(),file2.read()) 
file3.write("".join(result)), 

È possibile che questo frammento di codice produce una bella uscita memorizzato in un file chiamato "risultati", in formato stringa , mostrando le differenze tra i due file riga per riga. Tuttavia noto che se stampo semplicemente "risultato" senza utilizzando .join(), il compilatore restituisce un messaggio che include un indirizzo di memoria. Dopo aver provato a scrivere il risultato nel file senza utilizzando .join(), il compilatore mi ha informato che nel metodo .join() e non negli oggetti generatore possono essere utilizzate solo stringhe e buffer di caratteri. Quindi, in base al largo di tutte le prove che ho addotto, per favore correggetemi se sbaglio:

  1. result = diff.compare(file1.read(),file2.read()) < ---- risultato è un oggetto generatore?

  2. result è un elenco di stringhe, con result è di per sé il riferimento alla prima stringa?

  3. .join() prende un indirizzo di memoria e punta al primo e quindi scorre il resto degli indirizzi di stringhe in quella struttura?

  4. Un oggetto generatore è un oggetto che restituisce un puntatore?

Mi scuso se le mie domande non sono chiare, ma io fondamentalmente volevo chiedere i veterani pitone se le mie deduzioni erano corrette. La mia domanda è meno sui risultati osservabili, e molto più sui meccanismi interni di Python. Apprezzo tutto il tuo aiuto.

+0

Qual è il messaggio? – Marcin

+1

Non si dispone di un indirizzo di memoria; python ti fornisce una rappresentazione di un oggetto e l'impostazione predefinita per gli oggetti personalizzati è quella di mostrare il tipo e l'indirizzo di memoria dell'oggetto. C'è ancora un oggetto lì. –

risposta

22

join è un metodo di stringhe. Quel metodo prende qualsiasi iterabile e itera su di esso e unisce i contenuti insieme. (I contenuti devono essere stringhe o generano un'eccezione)

Se si tenta di scrivere l'oggetto generatore direttamente nel file, si otterrà solo l'oggetto generatore stesso, non il suo contenuto. join "srotola" il contenuto del generatore.

Si può vedere cosa sta succedendo con un semplice, generatore di esplicito:

def gen(): 
    yield 'A' 
    yield 'B' 
    yield 'C' 

>>> g = gen() 
>>> print g 
<generator object gen at 0x0000000004BB9090> 
>>> print ''.join(g) 
ABC 

Il generatore distribuisce i suoi contenuti, uno alla volta. Se provate a guardare il generatore stesso, non distribuisce nulla e lo vedete semplicemente come "oggetto generatore". Per ottenere il suo contenuto, è necessario iterare su di loro. È possibile farlo con un ciclo for, con la funzione next o con una qualsiasi delle varie altre funzioni/metodi che iterano su cose (str.join tra di loro).

Quando dici che il risultato "è un elenco di stringhe" ti stai avvicinando all'idea. Un generatore (o iterabile) è un po 'come una "lista potenziale". Anziché effettivamente è un elenco di tutti i suoi contenuti tutto in una volta, ti consente di staccare ogni articolo uno alla volta.

Nessuno degli oggetti è un "indirizzo di memoria".La rappresentazione della stringa di un oggetto generatore (come quella di molti altri oggetti) include un indirizzo di memoria, quindi se lo stampi (come sopra) o lo scrivi in ​​un file, vedrai quell'indirizzo. Ma ciò non significa che l'oggetto "è" quell'indirizzo di memoria, e l'indirizzo stesso non è realmente utilizzabile come tale. È solo un comodo tag identificativo in modo che se hai più oggetti puoi distinguerli.

+2

Si noti che 'join' presuppone che l'iterabile contenga/restituisca solo stringhe. Si lamenterà se questo non è il caso ... – mgilson

+6

Fatto interessante: dare ''' .join()' un generatore è * più lento * di dare ''' .join()' il risultato della chiamata di 'list() 'su un generatore. ''' .join (list (result))' è più veloce di ''' .join (result)'. –

+0

@Marcin: Il messaggio era: eazar001

Problemi correlati