2013-03-19 28 views
5

Sto provando a sovrascrivere un file. Ho basato la mia risposta su questo Read and overwrite a file in PythonCome sovrascrivere un file in Python?

Per completare i miei codici:

<select class="select compact expandable-list check-list" 
    ONCHANGE="location = this.options[this.selectedIndex].value;"> 
    <option value="{% url envelopes:auto_sort %}?sort_by=custom"> 
     Custom order 
    </option> 
    <optgroup label="Category"> 
     <option value="{% url envelopes:auto_sort %}?sort_by=cat_asc"> 
      Ascending order 
     </option> 
     <option value="{% url envelopes:auto_sort %}?sort_by=cat_desc"> 
      Descending order 
     </option> 
    </optgroup> 
</select> 

def auto_sort(request): 
    sort_by = request.GET.get('sort_by', None) 
    if sort_by: 
     temp_path = "{0}/file.txt".format(settings.SITE_ROOT) 

     f=open(temp_path,'r+') 
     text = f.read() 
     text = re.sub('cat_asc', 'cat_desc', text) 
     f.seek(0) 
     f.write(text) 
     f.truncate() 
     f.close(); 

     handle=open(temp_path,'w+') 
     handle.write(sort_by) 
     handle.close(); 

    return HttpResponseRedirect(reverse('envelopes:editor')) 

L'uscita dei miei attuali codici:

Il file contiene cat_desc quando provo riscrivere ancora una volta come custom. Riscrive come customc. Si noti il ​​c alla fine, deve essere solo custom.

Qui è quello che sto cercando di realizzare:

  1. scrivo su file, ad esempio, cat_desc
  2. Se voglio scrivere di nuovo, per esempio custom, il cat_desc deve essere rimosso e sostituito con custom.
+3

Quale linea è l'errore che si verificano su? – Serdalis

+0

http://docs.python.org/2/library/re.html#re.sub re.sub accetta tre argomenti stringa 'pattern'/'replacement', 'string'. Il quarto argomento (il tuo argomento "testo") deve essere un numero che specifica il conteggio – RedBaron

+0

Qual è la linea con 're.sub' _supposed_ da fare? I parametri sono in diversi ordini nella domanda e nel traceback! –

risposta

4

Sulla base della sua domanda di revisione, forse qualcosa di simile sarebbe più semplice

def auto_sort(request): 
    sort_by = request.GET.get('sort_by', None) 
    if sort_by: 
     temp_path = "{0}/file.txt".format(settings.SITE_ROOT) 
     #Set new_text to whatever you want based on your logic 
     new_text = 'custom' 
     f=open(temp_path,'w') 
     f.write(new_text) 
     f.close(); 

     handle=open(temp_path,'w+') 
     handle.write(sort_by) 
     handle.close(); 

    return HttpResponseRedirect(reverse('envelopes:editor')) 
+0

ottengo l'errore di nuovo 'TypeError: è richiesto un numero intero ». Questo è l'errore prima. – catherine

+0

rimuovere la parte re.sub. Non è necessario che – RedBaron

+0

E 'ora di lavoro, mi limiterò a provare questa – catherine

-1

Puoi copiare e incollare l'errore terzino

Prova:

def auto_sort(request): 
    sort_by = request.GET.get('sort_by', None) 
    if sort_by: 
     temp_path = "{0}/file.txt".format(settings.SITE_ROOT) 
     f=open(temp_path,'r') 
     text = f.read() 
     text = re.sub('custom', 'cat_asc', 'cat_desc', text) 
     f.close(); 
     handle=open(temp_path,'w') 
     handle.write(sort_by) 
     handle.close(); 
    return HttpResponseRedirect(reverse('envelopes:editor')) 
+0

stesso errore ancora – catherine

5

Nuova anwser ...

si sta passando text come il 4 ° parametro di re.sub. Questo dovrebbe essere un int

Help on function sub in module re: 

sub(pattern, repl, string, count=0, flags=0) 
    Return the string obtained by replacing the leftmost 
    non-overlapping occurrences of the pattern in string by the 
    replacement repl. repl can be either a string or a callable; 
    if a string, backslash escapes in it are processed. If it is 
    a callable, it's passed the match object and must return 
    a replacement string to be used. 

risposta vecchia ...

Forse si stanno facendo

from os import open 

Questo è un diverso (livello inferiore) aperta, si vuole basta usare l'open integrato (non è necessario importare nulla per usarlo)

Ecco un exa mple di farlo sbagliato e ottenere il vostro messaggio di errore

>>> from os import open 
>>> open("some_path", "r+") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: an integer is required 

anche per sovrascrivere il file, è necessario aprire con "w +". "r" sta per read

+0

Non ho usato 'da os import open' – catherine

+0

@catherine, Ok. il problema non ha nulla a che fare con la sovrascrittura del file, è il wat che stai usando 're.sub' –

2

Il tuo problema non ha nulla a che fare con la scrittura di un file.

Il traceback ti dice che questa linea è il colpevole:

File "/home/cath/src/envelopebudget/envelopebudget/settings/../apps/envelopes/views.py" in auto_sort 
    357.   text = re.sub('cat_desc', 'cat_asc', 'custom', text) 

Se si guarda il metodo re.sub, si sta chiamando sbagliato:

re.sub(pattern, repl, string, count=0, flags=0) 

si sta passando 'cat_desc' come il pattern, 'cat_asc' come repl, 'custom' come string e text come count. Non ha alcun senso. re.sub si aspetta che il valore count sia un numero intero e che gli sia stata assegnata una stringa.

+0

ok ho già cancellato l'abitudine e ora funziona. Ma quello che sto cercando di ottenere è di riscrivere completamente il file. – catherine

+0

@catherine: OK, ma se questo è non funziona, hai un problema completamente diverso, e avrete bisogno di dirci di cosa si tratta in dettaglio, preferibilmente in una nuova domanda. – abarnert

+0

È consentito creare una nuova domanda? Il mio problema è sovrascrivere il file che ho inserito come titolo. – catherine

5

Per la vostra nuova domanda:

Cercando di sovrascrivere un file sul posto è praticamente impossibile, a meno che non si sta sostituendo stringhe di byte con le nuove stringhe di byte della stessa lunghezza. Se sostituisci 'cat_desc' con 'cat_asc', finirai con 'cat_ascc'.

Che cosa stai facendo: aprirlo in modalità 'r+', leggere tutto, elaborarlo, seek a 0, e scrivere l'intera cosa, funziona. Ma non è il modo migliore di fare le cose.

E in ogni caso, il tuo problema è che immediatamente dopo averlo fatto, apri lo stesso identico percorso nella modalità 'w+' (che tronca il file) e scrivi qualcosa di diverso. Quindi, qualsiasi cosa tu abbia scritto ora è andata.

La soluzione è ... non farlo. Non sono sicuro di cosa stavi cercando di fare, ma probabilmente non è così.

Nel frattempo, il modo migliore per riscrivere un file è l'idioma "scrittura e rinominazione atomica". Questo garantisce che non si corrompa mai il file, o si ottiene il nuovo file o si ha ancora quello vecchio. Significa anche che non è necessario mantenere l'intero file in memoria; puoi andare a poco a poco. Ed è molto semplice ... se non ti interessa Windows. Funziona così:

with tempfile.NamedTemporaryFile(delete=False) as outfile: 
    with open(inpath) as infile: 
     # copy from infile to outfile, changing things as you go 
    os.rename(outfile.name, inpath) 

Sfortunatamente, rendere questo lavoro su Windows è molto doloroso. Non è possibile spostare outfile mentre è ancora aperto e non è possibile accedervi al di fuori dell'istruzione with e per di più non si può semplicemente sovrascrivere lo infile con outfile; devi fare un complicato shuffle. E non sarà mai completamente atomico, a meno che tu non voglia richiedere Vista/2008 e chiamare direttamente le API Win32.

+0

grazie Capisco ora perché ho che l'uscita – catherine

Problemi correlati