2013-03-19 9 views
5

Я пытаюсь переписать файл. Я основан мой ответ на этот Read and overwrite a file in PythonКак перезаписать файл в Python?

Чтобы закончить свои коды:

<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')) 

Выход из моих текущих кодов:

Файл содержит cat_desc при попытке переписать снова custom. Он переписывается как customc. Обратите внимание на c в конце, это должно быть только custom.

Вот что я пытаюсь достичь:

  1. Я пишу на файл, например, cat_desc
  2. Если я хочу написать еще раз, например custom, то cat_desc должны быть удалены и заменен на custom.
+3

Какой линии ошибка происходит на? – Serdalis

+0

http://docs.python.org/2/library/re.html#re.sub re.sub принимает три строковых аргумента 'pattern'/'replacement', 'string'. Четвертый аргумент (ваш «текстовый» аргумент) должен быть числом, определяющим счет – RedBaron

+0

. Какова строка с 're.sub' _supposed_? Параметры находятся в разных порядках в вопросе и трассировке! –

ответ

4

Основываясь на исправленный вопрос, может быть что-то подобное было бы проще

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

Я снова получаю ошибку 'TypeError: требуется целое число ». Это ошибка раньше. – catherine

+0

удалите деталь re.sub. Он вам не нужен – RedBaron

+0

Сейчас он работает, я просто испытаю это – catherine

-1

Вы можете скопировать и вставить полную ошибку назад

Try:

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

такая же ошибка снова – catherine

5

Новый anwser ...

Вы проходя text как 4 параметра re.sub. Это должно быть 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. 

старый ответ ...

Возможно, вы делаете

from os import open 

Это другой (нижний уровень) открыт, вы хотите просто используйте встроенный open (вам не нужно импортировать что-либо для его использования)

Адрес: exa mple делать это неправильно и получить ваше сообщение об ошибке

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

Также для перезаписи файла, вам необходимо открыть с «ш +». «r» означает:

+0

Я не использовал 'from os import open' – catherine

+0

@catherine, Ok. проблема не имеет ничего общего с переписыванием файла, это ват, который вы используете 're.sub' –

2

Ваша проблема не имеет ничего общего с записью файла.

отслеживающий говорит вам, что эта линия является виновником:

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

Если посмотреть на метод re.sub, вы вызываете его неправильно:

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

Вы проходя 'cat_desc' в pattern, 'cat_asc' как repl, 'custom' как string, и text как count. Это не имеет никакого смысла. re.sub ожидает, что count будет целым числом, и вы дали ему строку.

+0

ok Я уже стираю таможню, и она работает сейчас. Но я пытаюсь полностью переписать файл. – catherine

+0

@catherine: Хорошо, но если это не работает, у вас есть совершенно другая проблема, и вам нужно будет рассказать нам, что это подробно, желательно в новом вопросе. – abarnert

+0

Можно ли создать новый вопрос? Моя проблема - перезаписать файл, который я поставил как заголовок. – catherine

5

Для вашего нового вопроса:

Попытка переписать файл на месте в принципе невозможно, если только вы не заменяя байтовые строки с новыми байтовых строк точно такой же длины. Если вы замените 'cat_desc' на 'cat_asc', вы получите 'cat_ascc'.

Что вы делаете - открываете его в режиме 'r+', читая все это, обрабатывая его, seek Входя на 0, и записывая все это - работает. Но это не лучший способ сделать что-то.

И, во всяком случае, ваша проблема заключается в том, что сразу после этого вы открываете тот же самый путь в режиме 'w+' (который обрезает файл) и записывают что-то другое. Итак, все, что вы написали, теперь исчезло.

Решение этого вопроса ... не делайте этого. Я не уверен, что вы пытались сделать, но это, вероятно, не так.

Между тем, лучший способ переписать файл - это «атомная запись темпа и переименование» идиомы. Это гарантирует, что вы никогда не повредите файл, либо получите новый файл, либо сохраните старый файл. Это также означает, что вам не нужно хранить весь файл в памяти; вы можете идти по частям. И это очень просто ... если вы не заботитесь о Windows. Он работает следующим образом:

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) 

К сожалению, для этой работы в Windows очень больно. Вы не можете перемещать outfile, пока он по-прежнему открыт, и вы не можете получить к нему доступ за пределами инструкции with, и, кроме того, вы не можете просто перезаписать infile с помощью outfile; вам нужно сделать сложную перетасовку. И он никогда не будет полностью атомарным, если вы не захотите требовать Vista/2008 и напрямую обращаться к API Win32.

+0

спасибо, я понимаю, почему я получаю этот вывод – catherine

Смежные вопросы