Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to overwrite a file in Python?

Tags:

python

file

I'm trying to overwrite a file. I based my answer on this Read and overwrite a file in Python

To complete my codes:

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

The output of my current codes:

The file contains cat_desc when I try rewrite again as custom. It rewrites as customc. Notice the c at the end, it must be custom only.

Here is what I'm trying to achieve:

  1. I write on file, for example, cat_desc
  2. If I want to write again, for example custom, the cat_desc must be removed and replaced with custom.
like image 796
catherine Avatar asked Mar 19 '13 04:03

catherine


People also ask

How do I overwrite an existing file?

Overwriting a File, Part 1 To edit the settings for a file, locate the file you wish to overwrite and hover over the file name. Click the chevron button that appears to the right of the file name and select Overwrite File from the menu.

Does Python write overwrite?

Basics of Writing Files in Python Available are two modes, writing to a new file (and overwriting any existing data) and appending data at the end of a file that already exists.

Does Python open W overwrite?

w : Opens in write-only mode. The pointer is placed at the beginning of the file and this will overwrite any existing file with the same name.


3 Answers

New anwser ...

You're passing text as the 4th parameter of re.sub. This is supposed to be an 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.

old answer ...

Perhaps you are doing

from os import open

That is a different (lower level) open, you want to just use the builtin open (you don't need to import anything to use it)

Here is an example of doing it wrong and getting your error message

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

Also to overwrite the file, you need to open with "w+". "r" stands for read

like image 193
John La Rooy Avatar answered Oct 23 '22 02:10

John La Rooy


For your new question:

Trying to overwrite a file in-place is basically impossible, unless you're replacing byte strings with new byte strings of the exact same length. If you replace 'cat_desc' with 'cat_asc', you're going to end up with 'cat_ascc'.

What you're doing—opening it in 'r+' mode, reading the whole thing, processing it, seeking to 0, and writing the whole thing—does work. But it's not the best way to do things.

And at any rate, your problem is that immediately after you do this, you open the exact same path in 'w+' mode (which truncates the file) and write something different. So, whatever you wrote is now gone.

The solution to that is… don't do that. I'm not sure what you were trying to do, but that probably isn't it.

Meanwhile, the best way to rewrite a file is the "atomic write temp and rename" idiom. This guarantees that you never corrupt the file, you either get the new file or still have the old one. It also means you don't have to keep the whole file around in memory; you can go bit by bit. And it's very simple… if you don't care about Windows. It works like this:

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)

Unfortunately, making this work on Windows is very painful. You can't move outfile while it's still open, and you can't access it outside the with statement, and on top of that you can't just overwrite infile with outfile; you have to do a complicated shuffle. And it's never going to be completely atomic, unless you're willing to require Vista/2008 and to call Win32 APIs directly.

like image 37
abarnert Avatar answered Oct 23 '22 00:10

abarnert


Based on your revised question, maybe something like this would be simpler

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'))
like image 4
RedBaron Avatar answered Oct 23 '22 00:10

RedBaron